正確避免浮點數計算偏差問題

正確避免浮點數計算偏差問題 Filed Under : 业界博客 by admin 五.17,2011 来源博客:RichMedia+ 不管是用哪一種語言,只要關於浮點數運算一定會出現偏差 譬如 AS3 or Javascript 執行 152.2938 * 100 會輸出 15229.380000000001 當然最精確的作法是改用大數 BigDecimal 類別 假如一般不需要用到那麼精確,又要避開浮點數運算偏差的問題 最常見的作法可能就是直接用浮點數乘 100,四捨五入之後再除以 100 了 網路上很多現成的 function 可以用 function roundFloat(value:Number,divider:Number):Number{  return Math.round(value * divider) / divider; } 問題來了,那個除數大小到底該怎樣決定呢? 你可能會覺得很簡單,需要精確到小數下兩位就用 100,精確到三位就用 1000 可是這樣的用法正確嗎? 雙精度浮點數有效位數是 15 位 整數位數多,小數有效位數就減少,反之亦然 倘若整數占了 13 位,算式精確到小數 3 位只是自己騙自己而已 倘若整數占了 3 位,算式精確到小數 3 位則是浪費浮點數的有效位數 很明顯固定抓小數 3 位的作法無法適用絕大部分情況 假如需要計算整數位數少,小數位數多情況 就增加 divider 參數,反之就要縮小 divider 無法用同一個算式計算大小不同的數值 這樣寫法實在有點笨 而且上面 function 內容真的很少,為了這問題 所有的地方都要 import 並呼叫這個 function 好像有點過頭了 倘若全部都改成 inline 的算式好像又顯得雜亂 畢竟每個地方用到的 divider 大小可能不一樣 以下分享一個更簡單的作法,且能更有效的利用浮點數所有的有效位數 利用 Number.toPrecision 指定轉成固定精確度 15 的字串 這樣一轉,有效位數的浮點數計算偏差就被去除掉了 然後再用 parseFloat 轉回浮點數 實際測試範例: // 整數位數五位的情況,能夠進行到小數下 8 位的運算不受偏差影響 var no:Number = (152.2938 * 100) + 0.00000001; trace(no); // 15229.380000010002 &lt;- 浮點數計算偏差 trace(parseFloat(no.toPrecision(15))); // 15229.38000001 <- 修正浮點數計算偏差 // 整數位數 10 位的情況,能夠進行到小數下 3 位的運算不受偏差影響 var no:Number = 1234567890; for (var i:int = 0 ; i < 9 ; ++i) {  trace(no += 0.011);  trace(no = parseFloat(no.toPrecision(15))); } /*/ 1234567890.011 1234567890.011 1234567890.0219998  <- 浮點數計算偏差 1234567890.022      <- 修正浮點數計算偏差 1234567890.033 1234567890.033 1234567890.044 1234567890.044 1234567890.0549998  <- 浮點數計算偏差 1234567890.055      <- 修正浮點數計算偏差 1234567890.066 1234567890.066 1234567890.077 1234567890.077 1234567890.0879998  <- 浮點數計算偏差 1234567890.088      <- 修正浮點數計算偏差 1234567890.099 1234567890.099 //*/ 除了 Number.toPrecision 之外也可以使用 Number.toExponential trace(Number(no.toExponential(15))); 以上的方式簡單到根本沒有必要獨立寫成一個 function,也不需要設置不同參數 一律 inline 使用就好了 Related posts:     Flex 3 Style Module     Flex 4 Style Module     Create Trail information & Expired Date in ActionScript3 & Flex

相关文章

一:display:flex布局display:flex是一种布局方式。它即可以...
1. flex设置元素垂直居中对齐在之前的一篇文章中记载过如何...
移动端开发知识点pc端软件和移动端apppc端软件是什么,有哪些...
最近挺忙的,准备考试,还有其他的事,没时间研究东西,快周...
display:flex;把容器设置为弹性盒模型(设置为弹性盒模型之后...
我在网页上运行了一个Flex应用程序,我想使用Command←组合键...