ceil
10 なら 10、 11 なら 20 になる関数を作りたい - IT戦記
Math.ceil は意地でも使いたくないという話かな。
((+x + a * .9) / a | 0) * a
とか?
$ cat test.js f = eval('function(x,a)'+ readline()); for each(a in [100, 10, 1, .1, .01, .001]) print([f(x,a) for each(x in [1234, 123.4, 12.34, 1.234, .1234])]); $ echo "x + a - (x % a || a)" | js test.js 1300,200,100,100,100 1240,130,20,10,10 1234,124,13,2,1 1234,123.4,12.4,1.3000000000000003,0.2 1234,123.41000000000001,12.34,1.24,0.13 1234,123.40100000000001,12.34,1.234,0.124 $ echo "((+x + a * .9) / a | 0) * a" | js test.js 1300,200,100,0,0 1240,130,20,10,0 1234,124,13,2,1 1234,123.4,12.4,1.3,0.2 1234,123.4,12.34,1.24,0.13 1234,123.4,12.34,1.234,0.124
+
指摘に応えてテストを変えた。
$ cat test.js f = eval('function(x,a)'+ readline()); for each(a in [100, 10, 1, .1, .01, .001]) print([f(x,a) for each(x in [1001, 100.1, 10.01, 1.001, .0001])]); $ echo "x + a - (x % a || a)" | js test.js 1100,200,100,100,100 1010,110,20,10,10 1001,101,11,2,1 1001.0000000000001,100.1,10.1,1.1,0.1 1001,100.10000000000001,10.01,1.01,0.01 1001,100.10000000000001,10.01,1.001,0.001 $ echo "((+x + a * .9) / a | 0) * a" | js test.js 1000,100,100,0,0 1010,100,10,10,0 1001,101,10,1,0 1001,100.10000000000001,10,1,0 1001,100.10000000000001,10.01,1,0 1001,100.10000000000001,10.01,1.0010000000000001,0.001 $ echo "((x - 1e-13 + a) / a | 0) * a" | js test.js 1100,200,100,100,100 1010,110,20,10,10 1001,101,11,2,1 1001,100.10000000000001,10.100000000000001,1.1,0.1 1001,100.10000000000001,10.01,1.01,0.01 1001,100.10000000000001,10.01,1.0010000000000001,0.001 $ echo "Math.ceil(x / a) * a" | js test.js 1100,200,100,100,100 1010,110,20,10,10 1001,101,11,2,1 1001,100.10000000000001,10.100000000000001,1.1,0.1 1001,100.10000000000001,10.01,1.01,0.01 1001,100.10000000000001,10.01,1.0010000000000001,0.001
この1e-14のブレはどうしようも無いのかな。