« GROW A XMAS TREE | Home | 中央環状線トンネルウォーク »

Dec 102007

Math.floorで・・・・

こんなかんじ。

a = 0.6;
b = 0.1;
c = 0.6/0.1;
trace(c);//output >6
trace(Math.floor(c));//output > 5

Math.floorの問題というよりも、浮動小数点の問題じゃないかな?一応少数14桁まではTraceで出力されるが、今回はその先で誤差が入っているのだと思う。Flashは(他のプログラムでもそうなのかもしれないが)浮動小数点の問題はこの辺(http://3dal.jp/blog/2007/10/post_63.html)のように加算でも発生する場合がある。

ただ今回は除算が原因なので、とりあえず対応策は

a = 0.6;
c = 0.1;
d = 1/c;
b = a*d;
trace(b);//output > 6
a = Math.floor(b);
trace(a);//output >6

これでOK。(数学的にはやっていることは何一つ変わっていないけど・・・)まぁ処理スピードのこととかも考えると出来るだけ除算は使用しないに越したことはないですね。


しかしこんなの普通気づかないよ・・・。
数式の正当性とかから疑い始めると仕事にならんですたい。

追記:10-Dec-2007 15:56:14
除算の問題ではなく、もうこのレベルの問題。

a = 0;
addV = 0.1;
var nLoop = 100;
for (var i = 0; i<=nLoop; i++) {
a += addV;
b = a*10;
trace([b, Math.floor(b)]);

}

これで

1,1
2,2
3,3
4,4
5,5
6,6
7,7
8,7
9,9
10,9
11,10
12,12
13,13
14,14
15,15
16,16
17,17
18,18
19,19
20,20
21,21
22,22
23,23
24,24
25,25
26,26
27,27
28,28
29,29
30,30
31,31
32,32
33,33
34,34
35,35
36,36
37,37
38,38
39,39
40,40
41,41
42,42
43,43
44,44
45,45
46,46
47,46
48,47
49,48
50,49
51,50
52,51
53,52
54,53
55,54
56,55
57,56
58,57
59,58
59.9999999999999,59
60.9999999999999,60
61.9999999999999,61
62.9999999999999,62
63.9999999999999,63
64.9999999999999,64
65.9999999999999,65
66.9999999999999,66
67.9999999999999,67
68.9999999999999,68
69.9999999999999,69
70.9999999999999,70
71.9999999999999,71
72.9999999999999,72
73.9999999999999,73
74.9999999999999,74
75.9999999999999,75
76.9999999999999,76
77.9999999999999,77
78.9999999999999,78
79.9999999999999,79
80.9999999999999,80
81.9999999999999,81
82.9999999999999,82
83.9999999999999,83
84.9999999999999,84
85.9999999999999,85
86.9999999999999,86
87.9999999999998,87
88.9999999999998,88
89.9999999999998,89
90.9999999999998,90
91.9999999999998,91
92.9999999999998,92
93.9999999999998,93
94.9999999999998,94
95.9999999999998,95
96.9999999999998,96
97.9999999999998,97
98.9999999999998,98
99.9999999999998,99
101,100

こゆことだわ・・・。なので小数値で計算するなと・・いうこと。
じゃどーするか?っつーと計算の段階では整数に繰り上げて演算処理ということになるかな・・。

つまり上記の式を

a = 0;
addV = 1;
var nLoop = 100;
for (var i = 0; i<=nLoop; i++) {
a += addV;
b = a*1;
trace([b, Math.floor(b)]);

}

として計算。

結果は

1,1
2,2
3,3
4,4
5,5
6,6
7,7
8,8
9,9
10,10
11,11
12,12
13,13
14,14
15,15
16,16
17,17
18,18
19,19
20,20
21,21
22,22
23,23
24,24
25,25
26,26
27,27
28,28
29,29
30,30
31,31
32,32
33,33
34,34
35,35
36,36
37,37
38,38
39,39
40,40
41,41
42,42
43,43
44,44
45,45
46,46
47,47
48,48
49,49
50,50
51,51
52,52
53,53
54,54
55,55
56,56
57,57
58,58
59,59
60,60
61,61
62,62
63,63
64,64
65,65
66,66
67,67
68,68
69,69
70,70
71,71
72,72
73,73
74,74
75,75
76,76
77,77
78,78
79,79
80,80
81,81
82,82
83,83
84,84
85,85
86,86
87,87
88,88
89,89
90,90
91,91
92,92
93,93
94,94
95,95
96,96
97,97
98,98
99,99
100,100
101,101

こんな感じ。
も少し検証必要だけど・・。

ちとも少し検証。

9 Comments

解決か?と思ったけど、まだ細かい部分でバグってる・・・。

そもそも加算でも丸め誤差が積み上げられていくので乗算にしたって問題解決しない・・。

除算とかの問題じゃねえな・・。加算だ・・・orz

読んでてrotationの誤差を思い出しました。Flash以外ではこういうこと起きないんでしょうか?(;・∀・)

>rotationの誤差
これは逆に知らないのですが、なんでしょう?Flashのrotationにもそんな誤差がでてくるんですか??

>Flash以外ではこういうこと起きないんでしょうか?
いや発生すると思います。いわゆる丸め誤差って奴ですね。でも加算でも発生するってのは知らなかったです。他の言語でもそういう感じなのかは良くわからないです・・。

検索するとありました。これですー。
http://www.adobe.com/jp/support/director/ts/documents/dr0221.html

Flash以外でも発生するんですね……。気をつけないとハマりそうだなぁ。

回転の問題は初めて知りました。これってDirectorからFlashを操作したときの問題なんですかね??Flashだけでもこの問題は今でも発生するのだろうか??むむむ・・・。

liteで発生した記憶があったので探してみると、ここでも検討されてました。ご参考までに。
http://www.flash-jp.com/modules/newbb/viewprint.php?order=ASC&topic_id=2935&forum=8&PHPSESSID=bddbd78926d6ff64d8d56f8f8fe88529

ギャボー。
ありがとございます。

Leave a comment

Search and Archives