阿豆 發問時間: 電腦與網際網路程式設計 · 1 0 年前

MATLAB小程式BUG

close all;clear all;clc

low=-4;

i=1;

while i<=(4-(-4))/0.1 %這邊是為了計算間距為0.1時,有幾筆資料

abc(1,1)=low;

abc(i+1,1)=abc(i,1)+0.1; %abc矩陣即為 入值的矩陣

i=i+1;

end

跑出來的結果很怪

照理說 abc矩陣結果應該是從-4 , -3.9, -3.8, ... , 3.9, 4

可是有一些值不是到小數第一點

如果這個值應該顯示 -3 可是它實際上是 -2.999999999999999

應該是0 它卻是一個科學記號 2.414735078559716e-015

有大大可以跟我說這其中的奧妙嗎

我真的找不出個所以然

我怕會因為這樣

導致後面所代入的值有偏差

或者說有別的方法可以產生類似這樣的結果

範圍是(-4~4)、間隔為0.1

我試了好久

有想過用if 去做 可是我找不到可以取到小數第一點的指令或是相關指令

已更新項目:

版本R2007a

這個程式跑出來的值

我複製出來的也不會有問題

但是 我是直接在MATLAB上檢視abc矩陣的結果

假設我檢視abc(20,1)這個值 ,我點個兩下 就會發現以上怪現象

寫這個只是單純為了希望直接用程式產生 範圍是(-4~4)、間隔為0.1的值,希望程式能"活"一點

2 個已更新項目:

針對Charles的回答 我還是一頭霧水

簡單的來看 好像是跟64bit有關@@

但我不知道為什麼

不過我做過實驗了

間隔是

0.125 0.25 0.375 0.5 0.625 0.75 沒問題

0.123就有問題 0.11也有問題 0.113沒問題

無聊又測試了好幾個其他連續下來的

沒個規則 還是看唔= =

不知道可以講的容易一點? @@

3 個已更新項目:

2 個解答

評分
  • 1 0 年前
    最佳解答

    你的結果並不奇怪

    這是因為0.1這個浮點數(floating-point)的關係

    你可以試著了解浮點數先

    以下引用Matlab Help

    Double-Precision Floating Point

    MATLAB constructs the double-precision (or double) data type according to IEEE Standard 754 for double precision. Any value stored as a double requires 64 bits, formatted as shown in the table below:

    63

    Sign (0 = positive, 1 = negative)

    62 to 52

    Exponent, biased by 1023

    51 to 0

    Fraction f of the number 1.f

    你可以根據上面引言推算

    其實0.1並不是一個好表示的數

    比起0.125或0.0625而言 這2個數 還比較好表示

    2008-02-29 15:21:06 補充:

    我補充一下 dtsien的回答

    floating-point的確有rounding error的問題

    而用什麼matlab版本不是主要的關鍵,因為rounding error是一直存在的問題,但是你在matlab的command window列出數值的時候,你所看到的數值格式是由"format"所控制的

    2008-02-29 15:21:29 補充:

    以下是我用matlab的式範

    >> format long g

    >> abc

    abc =

    -4

    -3.9

    ...(省略)

    -1.2

    -1.1

    -0.999999999999997

    -0.899999999999997

    ...(省略)

    3.9

    4

    2008-02-29 15:21:34 補充:

    >> format short

    >> abc

    abc =

    -4.0000

    -3.9000

    ...(省略)

    -0.2000

    -0.1000

    0.0000

    0.1000

    0.2000

    0.3000

    ...(省略)

    3.9000

    4.0000

    >>

    2008-02-29 15:44:15 補充:

    由於你在程式在產生abc時,是用累加0.1的方式,所以rounding error會累積。

    再者回答你0.125為何不會產生問題,因為0.125正好有浮點數可以表示。

    比如說一個整數13 = 8 + 4 + 1 即 2^3 + 2^2 + 2^0 也就是 1101(二進位)

    而小數也是一樣,比如 0.125 = 1/8 即 2^(-3);

    0.375 = 0.25 + 0.125 即 2^(-2) + 2^(-3)

    舉個更小的數 0.03125 = 2^(-5)

    但你看0.1這個數,是不是比較難用2進位表示

    0.1 = 2^(-4) + 2^(-5) + ......

  • dtsien
    Lv 6
    1 0 年前

    你是用什麼板本在什麼機器跑的

    我跑一點問題都沒

    >> abc

    abc =

    -4.0000

    -3.9000

    -3.8000

    -3.7000

    -3.6000

    -3.5000

    -3.4000

    -3.3000

    -3.2000

    -3.1000

    -3.0000

    -2.9000

    -2.8000

    -2.7000

    -2.6000

    -2.5000

    -2.4000

    -2.3000

    -2.2000

    -2.1000

    -2.0000

    -1.9000

    -1.8000

    -1.7000

    -1.6000

    -1.5000

    -1.4000

    -1.3000

    -1.2000

    -1.1000

    -1.0000

    -0.9000

    -0.8000

    -0.7000

    -0.6000

    -0.5000

    -0.4000

    -0.3000

    -0.2000

    -0.1000

    0.0000

    0.1000

    0.2000

    0.3000

    0.4000

    0.5000

    0.6000

    0.7000

    0.8000

    0.9000

    1.0000

    1.1000

    1.2000

    1.3000

    1.4000

    1.5000

    1.6000

    1.7000

    1.8000

    1.9000

    2.0000

    2.1000

    2.2000

    2.3000

    2.4000

    2.5000

    2.6000

    2.7000

    2.8000

    2.9000

    3.0000

    3.1000

    3.2000

    3.3000

    3.4000

    3.5000

    3.6000

    3.7000

    3.8000

    3.9000

    4.0000

    雖說浮點算數會有 rounding error

    不過你這簡單的 case 輸出的值應該沒事的

還有問題?馬上發問,尋求解答。