:- module(numerics, [ user:('==>')/2 ]). % numeric-add numeric-add(3, 2) ==> data('decimal', [5]). 1.5 + 'NaN' ==> data('float', [nan]). 'NaN' + 1.5 ==> data('float', [nan]). 'INF' + -3 ==> data('float', [inf]). -3 + 'INF' ==> data('float', [inf]). '-INF' + 3 ==> data('float', [-inf]). 4.5 + '-INF' ==> data('float', [-inf]). 'INF' + 'INF' ==> data('double', [inf]). '-INF' + '-INF' ==> data('double', [-inf]). '-INF' + 'INF' ==> data('double', [nan]). 'INF' + '-INF' ==> data('double', [nan]). -1 + 5 ==> data('decimal', [4]). 1.2 + 1.8 ==> data('float', [3.0]). 1.4 + 1 ==> data('float', [2.4]). 1.5 + 1.5 + 1.5 ==> data('float', [4.5]). 2.4 + 1.6 + 'NaN' ==> data('float', [nan]). unsignedLong('3') + 2.5 ==> data('float', [5.5]). boolean('true') + 2.5 ==> false. % numeric-subtract numeric-subtract(3, 2) ==> data('decimal', [1]). 1.5 - 'NaN' ==> data('float', [nan]). 'NaN' - 1.5 ==> data('float', [nan]). 'INF' - 3 ==> data('float', [inf]). '-INF' - 1.2 ==> data('float', [-inf]). 5.25 - 'INF' ==> data('double', [-inf]). 5.25 - '-INF' ==> data('double', [inf]). 'INF' - 'INF' ==> data('float', [nan]). '-INF' - '-INF' ==> data('double', [nan]). 'INF' - '-INF' ==> data('double', [inf]). '-INF' - 'INF' ==> data('double', [-inf]). -1 - -2 ==> data('decimal', [1]). -2.3 - 1.7 ==> data('float', [-4.0]). 5 - 2.5 ==> data('float', [2.5]). 5 - 7 ==> data('decimal', [-2]). 13 - 7 - 8 ==> data('decimal', [-2]). 'INF' - 7 - 8 ==> data('float', [inf]). unsignedLong('3') - 1 ==> data('decimal', [2]). boolean('true') - 2.5 ==> false. % numeric-multiply numeric-multiply(3, 2) ==> data('decimal', [6]). 1.5 * 'NaN' ==> data('float', [nan]). 'NaN' * -1.5 ==> data('float', [nan]). 0 * '+INF' ==> data('double', [nan]). '-INF' * 0.0 ==> data('double', [nan]). 3 * 'INF' ==> data('float', [inf]). 3 * '-INF' ==> data('float', [-inf]). -3 * 'INF' ==> data('float', [-inf]). -3 * '-INF' ==> data('float', [inf]). 'INF' * 3 ==> data('float', [inf]). 'INF' * -3 ==> data('float', [-inf]). '-INF' * 3 ==> data('float', [-inf]). '-INF' * -3 ==> data('float', [inf]). 'INF' * 'INF' ==> data('double', [inf]). '-INF' * 'INF' ==> data('double', [-inf]). 'INF' * '-INF' ==> data('double', [-inf]). '-INF' * '-INF' ==> data('double', [inf]). -3 * 2 ==> data('decimal', [-6]). 0 * 0 ==> data('decimal', [0]). 'INF' * '-INF' * 0 ==> data('float', [nan]). 'INF' * -1 * 5 ==> data('float', [-inf]). 5 * 2 * 10 ==> data('decimal', [100]). unsignedLong('3') * 1.5 ==> data('float', [4.5]). boolean('true') * 2 ==> false. % numeric-divide numeric-divide(3, 2) ==> data('float', [1.5]). 1.5 div 'NaN' ==> data('float', [nan]). 'NaN' div -1.5 ==> data('float', [nan]). 5 div 0 ==> data('float', [inf]). 5 div -0 ==> data('float', [inf]). % should theoretically result in -inf -5 div 0 ==> data('float', [-inf]). -5 div -0 ==> data('float', [-inf]). % should theoretically result in inf 0 div 0 ==> data('double', [nan]). 0 div -0 ==> data('double', [nan]). -0 div 0 ==> data('double', [nan]). -0 div -0 ==> data('double', [nan]). 'INF' div 'INF' ==> data('double', [nan]). 'INF' div '-INF' ==> data('double', [nan]). '-INF' div 'INF' ==> data('double', [nan]). '-INF' div '-INF' ==> data('double', [nan]). 6 div 3 ==> data('decimal', [2]). 1.5 div 3 ==> data('float', [0.5]). 3 div 1.5 ==> data('float', [2.0]). 4.5 div 1.5 ==> data('double', [3.0]). % numeric-integer-divide numeric-integer-divide(3, 2) ==> data('integer', [1]). 1.5 idiv 'NaN' ==> false. 'NaN' idiv -1.5 ==> false. 5 idiv 0 ==> false. 5 idiv +0 ==> false. 5 idiv -0 ==> false. 'INF' idiv 3 ==> false. '+INF' idiv 3 ==> false. '-INF' idiv 3 ==> false. 'INF' idiv 'INF' ==> false. '-INF' idiv 'INF' ==> false. 'INF' idiv '-INF' ==> false. '-INF' idiv '-INF' ==> false. 5 idiv 'INF' ==> data('integer', [0]). 5 idiv '+INF' ==> data('integer', [0]). 5 idiv '-INF' ==> data('integer', [0]). 10 idiv 3 ==> data('integer', [3]). 3 idiv -2 ==> data('integer', [-1]). -3 idiv 2 ==> data('integer', [-1]). -3 idiv -2 ==> data('integer', [1]). 9.0 idiv 3 ==> data('integer', [3]). -3.5 idiv 3 ==> data('integer', [-1]). 3.0 idiv 4 ==> data('integer', [0]). 3.1E1 idiv 6 ==> data('integer', [5]). 3.1E1 idiv 7 ==> data('integer', [4]). % numeric-mod numeric-mod(3, 2) ==> data('decimal', [1]). decimal(1) mod decimal(0) ==> false. 'NaN' mod 3 ==> data('float', [nan]). 3 mod 'NaN' ==> data('double', [nan]). 'NaN' mod 'NaN' ==> data('float', [nan]). 'INF' mod 3 ==> data('float', [nan]). '-INF' mod 3 ==> data('float', [nan]). 1.5 mod 0 ==> data('float', [nan]). 1.5 mod -0 ==> data('float', [nan]). 'INF' mod 0 ==> data('float', [nan]). '-INF' mod 0 ==> data('float', [nan]). 'INF' mod -0 ==> data('float', [nan]). '-INF' mod -0 ==> data('float', [nan]). -3 mod 'INF' ==> data('float', [-3]). 3 mod '-INF' ==> data('float', [3]). 0 mod 3.5 ==> data('float', [0]). -0 mod 4 ==> data('float', [0]). 10 mod 3 ==> data('float', [1]). 6 mod -2 ==> data('decimal', [0]). 4.5 mod 1.2 ==> data('float', [0.9000000000000004]). 1.23e2 mod 0.6e1 ==> data('float', [3.0]). % numeric-unary-plus numeric-unary-plus(1) ==> data('decimal', [1]). +'NaN' ==> data('float', [nan]). +'INF' ==> data('float', [inf]). +'-INF' ==> data('float', [-inf]). +0.0 ==> data('float', [0.0]). +0 ==> data('decimal', [0]). +5 ==> data('decimal', [5]). +unsignedLong('3') ==> data('unsignedLong', [3]). +boolean('true') ==> false. % numeric-unary-minus numeric-unary-minus(1) ==> data('decimal', [-1]). -'NaN' ==> data('float', [nan]). -'INF' ==> data('float', [-inf]). -'-INF' ==> data('float', [inf]). -0.0 ==> data('float', [0.0]). -0 ==> data('decimal', [0]). -5 ==> data('decimal', [-5]). -unsignedLong('3') ==> data('unsignedLong', [-3]). -boolean('true') ==> false. % numeric-equal numeric-equal(1, 1) ==> data('boolean', [true]). % rest see eq, ne, le, ge % numeric-less-than numeric-less-than(1, 2) ==> data('boolean', [true]). % rest see lt, le % numeric-greater-than numeric-greater-than(2, 1) ==> data('boolean', [true]). % rest see gt, ge % eq 0 eq 0 ==> data('boolean', [true]). -0 eq +0 ==> data('boolean', [true]). 1 eq 1 ==> data('boolean', [true]). -1 eq +1 ==> data('boolean', [false]). 0 eq 1 ==> data('boolean', [false]). '-INF' eq '-INF' ==> data('boolean', [true]). '-INF' eq 'INF' ==> data('boolean', [false]). '+INF' eq 'INF' ==> data('boolean', [true]). 'INF' eq 'INF' ==> data('boolean', [true]). 1 eq 'INF' ==> data('boolean', [false]). '-INF' eq -999999999 ==> data('boolean', [false]). 'NaN' eq 'NaN' ==> data('boolean', [false]). 'NaN' eq 5 ==> data('boolean', [false]). unsignedLong('3') eq long('3') ==> data('boolean', [true]). % ne 0 ne 0 ==> data('boolean', [false]). -0 ne +0 ==> data('boolean', [false]). 1 ne 1 ==> data('boolean', [false]). -1 ne +1 ==> data('boolean', [true]). 0 ne 1 ==> data('boolean', [true]). '-INF' ne '-INF' ==> data('boolean', [false]). '-INF' ne 'INF' ==> data('boolean', [true]). '+INF' ne 'INF' ==> data('boolean', [false]). 'INF' ne 'INF' ==> data('boolean', [false]). 1 ne 'INF' ==> data('boolean', [true]). '-INF' ne -999999999 ==> data('boolean', [true]). 'NaN' ne 'NaN' ==> data('boolean', [true]). 'NaN' ne 5 ==> data('boolean', [true]). unsignedLong('3') ne long('3') ==> data('boolean', [false]). % le -1 le 0 ==> data('boolean', [true]). 0 le -1 ==> data('boolean', [false]). 0 le -0 ==> data('boolean', [true]). '-INF' le '-INF' ==> data('boolean', [true]). '-INF' le -3 ==> data('boolean', [true]). '-INF' le 'INF' ==> data('boolean', [true]). '-INF' le 'NaN' ==> data('boolean', [false]). 3 le 'INF' ==> data('boolean', [true]). 'INF' le 'INF' ==> data('boolean', [true]). 'NaN' le 'INF' ==> data('boolean', [false]). 'NaN' le 'NaN' ==> data('boolean', [false]). unsignedLong('3') le long('3') ==> data('boolean', [true]). % lt -1 lt 0 ==> data('boolean', [true]). 0 lt -1 ==> data('boolean', [false]). 0 lt -0 ==> data('boolean', [false]). '-INF' lt '-INF' ==> data('boolean', [false]). '-INF' lt -3 ==> data('boolean', [true]). '-INF' lt 'INF' ==> data('boolean', [true]). '-INF' lt 'NaN' ==> data('boolean', [false]). 3 lt 'INF' ==> data('boolean', [true]). 'INF' lt 'INF' ==> data('boolean', [false]). 'NaN' lt 'INF' ==> data('boolean', [false]). 'NaN' lt 'NaN' ==> data('boolean', [false]). unsignedLong('2') lt long('3') ==> data('boolean', [true]). % ge -1 ge 0 ==> data('boolean', [false]). 0 ge -1 ==> data('boolean', [true]). 0 ge -0 ==> data('boolean', [true]). '-INF' ge '-INF' ==> data('boolean', [true]). -3 ge '-INF' ==> data('boolean', [true]). 'INF' ge '-INF' ==> data('boolean', [true]). 'NaN' ge '-INF' ==> data('boolean', [false]). 'INF' ge 3 ==> data('boolean', [true]). 'INF' ge 'INF' ==> data('boolean', [true]). 'INF' ge 'NaN' ==> data('boolean', [false]). 'NaN' ge 'NaN' ==> data('boolean', [false]). unsignedLong('3') ge long('3') ==> data('boolean', [true]). % gt -1 gt 0 ==> data('boolean', [false]). 0 gt -1 ==> data('boolean', [true]). 0 gt -0 ==> data('boolean', [false]). '-INF' gt '-INF' ==> data('boolean', [false]). -3 gt '-INF' ==> data('boolean', [true]). 'INF' gt '-INF' ==> data('boolean', [true]). 'NaN' gt '-INF' ==> data('boolean', [false]). 'INF' gt 3 ==> data('boolean', [true]). 'INF' gt 'INF' ==> data('boolean', [false]). 'INF' gt 'NaN' ==> data('boolean', [false]). 'NaN' gt 'NaN' ==> data('boolean', [false]). unsignedLong('3') gt long('2') ==> data('boolean', [true]). % abs abs(-0) ==> data('decimal', [0]). abs(+0) ==> data('decimal', [0]). abs(-10.5) ==> data('float', [10.5]). abs(10.5e2) ==> data('float', [10.5e2]). abs('NaN') ==> data('float', [nan]). abs('-INF') ==> data('float', [inf]). abs('INF') ==> data('float', [inf]). abs('+INF') ==> data('float', [inf]). abs('1') ==> data('decimal', [1]). abs('STRING') ==> false. % ceiling ceiling(-0) ==> data('decimal', [0]). ceiling(+0) ==> data('decimal', [0]). ceiling(-10.5) ==> data('float', [-10]). ceiling(10.5) ==> data('float', [11]). ceiling('NaN') ==> data('float', [nan]). ceiling('-INF') ==> data('float', [-inf]). ceiling('INF') ==> data('float', [inf]). ceiling('+INF') ==> data('float', [inf]). ceiling('1') ==> data('decimal', [1]). ceiling('STRING') ==> false. % floor floor(-0) ==> data('decimal', [0]). floor(+0) ==> data('decimal', [0]). floor(-10.5) ==> data('float', [-11]). floor(10.5) ==> data('float', [10]). floor('NaN') ==> data('float', [nan]). floor('-INF') ==> data('float', [-inf]). floor('INF') ==> data('float', [inf]). floor('+INF') ==> data('float', [inf]). floor('1') ==> data('decimal', [1]). floor('STRING') ==> false. % round round(-0) ==> data('decimal', [0]). round(+0) ==> data('decimal', [0]). round(-10.5) ==> data('float', [-10]). round(-11.5) ==> data('float', [-11]). round(10.5) ==> data('float', [11]). round(11.5) ==> data('float', [12]). round('NaN') ==> data('float', [nan]). round('-INF') ==> data('float', [-inf]). round('INF') ==> data('float', [inf]). round('+INF') ==> data('float', [inf]). round('1') ==> data('decimal', [1]). round('STRING') ==> false. % round-half-to-even round-half-to-even(-0) ==> data('decimal', [0]). round-half-to-even(+0) ==> data('decimal', [0]). round-half-to-even(-11.6) ==> data('float', [-12]). round-half-to-even(-11.5) ==> data('float', [-12]). round-half-to-even(-11.4) ==> data('float', [-11]). round-half-to-even(-10.6) ==> data('float', [-11]). round-half-to-even(-10.5) ==> data('float', [-10]). round-half-to-even(-10.4) ==> data('float', [-10]). round-half-to-even(10.4) ==> data('float', [10]). round-half-to-even(10.5) ==> data('float', [10]). round-half-to-even(10.6) ==> data('float', [11]). round-half-to-even(11.4) ==> data('float', [11]). round-half-to-even(11.5) ==> data('float', [12]). round-half-to-even(11.6) ==> data('float', [12]). round-half-to-even(3.567812E+3, 2) ==> data('float', [3567.81]). round-half-to-even(4.7564E-3, 2) ==> data('float', [0.0]). round-half-to-even(35612.25, -2) ==> data('float', [35600]). round-half-to-even('NaN') ==> data('float', [nan]). round-half-to-even('-INF') ==> data('float', [-inf]). round-half-to-even('INF') ==> data('float', [inf]). round-half-to-even('+INF') ==> data('float', [inf]). round-half-to-even('1') ==> data('decimal', [1]). round-half-to-even('STRING') ==> false.