討論區快速選單
知識庫快速選單
軟體開發過程中有哪些資安漏洞? 網路投保旅行平安險 傑米的攝影旅遊筆記
[ 回上頁 ] [ 討論區發言規則 ]
原來在 PI 附近, <math.h> 的 sin(x) 是不會 0 啊!
更改我的閱讀文章字型大小
作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2170 | 人氣 89850 | 評價 10100 | 評價/貼文 4.65 | 送出評價 79 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/1/14 上午 12:09:51
剛剛在寫一個幾何的程式, 需要去算 sin(x) 的. 可是, sin(PI) 回傳值竟然不是 0 啊.
想了一想, 這也會理的, PI 是無理數, 以 double precision floating point 表達,
只可能是一個近似值. sin( PI的近似值 ), 不是 0, 也是情理之中的事.

可是, 這麼說的話, 數算所有在PI附近 的 double precision floating point 數值,
sin( 這些數值 ) 會是多少呢? 會不會有一個 滄海遺珠, 可以令 sin(x) 是 0 呢?

嗯嗯, 隨手編了下面的程式, 把 PI附近 的 double precision floating point 數值
數算下次, 並且檢查一下 sin(x) 是多少. 結果呢... 原來在 PI 附近, <math.h> 的 sin(x)
是不會 0 的.

x 在 PI 附近, 最接近 sin(x) = 0 的前後兩個數值是...
  sin(3.141592653589793116) = 0.000000000000000122
  sin(3.141592653589793560) = -0.000000000000000322

( ^^"... 好有趣的一個小習題, 分享一下. 不過呢... 如果你也覺得這是有趣的話...
趕緊去看醫生吧, 病向淺中醫呀)
作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2170 | 人氣 89850 | 評價 10100 | 評價/貼文 4.65 | 送出評價 79 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/1/14 上午 12:11:00
下面原碼的執行結果...

Using bisection method, theta converged in 121 iterations.
  sin(theta) = 0.000000000000000122 (i.e. 1.224646799147353207e-16)
  theta0 = 3.141592653589792672e+00
  theta = 3.141592653589793116e+00
  theta1 = 3.141592653589794004e+00

In binary sense,
  theta0 = 1.1001001000011111101101010100010001000010110100010111 x 2^1
  theta = 1.1001001000011111101101010100010001000010110100011000 x 2^1
  theta1 = 1.1001001000011111101101010100010001000010110100011010 x 2^1

 1.1001001000011111101101010100010001000010110100011000 x 2^1
Scan through the range (theta0,theta1) in binary sense, we have ...
  sin(3.141592653589792672) = 0.000000000000000567
  sin(3.141592653589793116) = 0.000000000000000122
  sin(3.141592653589793560) = -0.000000000000000322
  sin(3.141592653589794004) = -0.000000000000000766

  (i.e.
    sin(3.141592653589792672) = 5.665538897647979615e-16
    sin(3.141592653589793116) = 1.224646799147353207e-16
    sin(3.141592653589793560) = -3.216245299353273201e-16
    sin(3.141592653589794004) = -7.657137397853898870e-16
  )
作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2170 | 人氣 89850 | 評價 10100 | 評價/貼文 4.65 | 送出評價 79 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/1/14 上午 12:11:24
原碼...

#include <stdio.h>
#include <math.h>
#include <float.h>

void extract_double( double x, unsigned __int64 &sign_bit, unsigned __int64 &exponent, unsigned __int64 &fraction )
{
  unsigned __int64 val = (*((unsigned __int64*)&x));
  sign_bit = val & 0x8000000000000000uL;
  sign_bit = (sign_bit>>63);
  exponent = (val & 0x7FF0000000000000UL)>>52;
  fraction = val & 0x000FFFFFFFFFFFFFuL;
}

double get_double( unsigned __int64 sign_bit, unsigned __int64 exponent, unsigned __int64 fraction )
{
  unsigned __int64 val = (sign_bit<<63) | (exponent<<52) | fraction;
  return *((double*)&val);
}

void printf_double( double x )
{
  unsigned __int64 val = (*((unsigned __int64*)&x));
  unsigned __int64 sign_bit = val & 0x8000000000000000UL;
  sign_bit = (sign_bit>>63);
  unsigned __int64 exponent = (val & 0x7FF0000000000000UL)>>52;
  unsigned __int64 fraction = val & 0x000FFFFFFFFFFFFFUL;
  int i;

  if( sign_bit )
    printf( "-" );
  else
printf( " " );

  if( exponent )
  {
    printf( "1." );
    for( i=51; i>=0; i-- )
     printf( "%i", (fraction>>i) & 1 );
    printf( " x 2^%i", exponent-1023 );
  }else
{
    printf( "0." );
    for( i=51; i>=0; i-- )
     printf( "%i", (fraction>>i) & 1 );
    printf( " x 2^%i", 1-1023 );
  }
}

void main()
{
  int i;
  double theta0 = 2;
  double theta1 = 4;
  double thetat0;
  double theta;
  for( i=0; 1; i++ )
  {
    theta = (theta0+theta1)/2;
    if( sin(theta) > 0 )
     theta0 = (theta0+theta)/2;
    else if( sin(theta) < 0 )
     theta1 = (theta+theta1)/2;
    if( (theta0+theta1)/2==theta )
    {
     theta = (theta0+theta1)/2;
     break;
    }
  }
  printf( "Using bisection method, theta converged in %i iterations.\n", i );
  printf( " sin(theta) = %.18f (i.e. %.18le)\n", sin(theta), sin(theta) );
  printf( " theta0 = %.18le\n", theta0 );
  printf( " theta = %.18le\n", theta );
  printf( " theta1 = %.18le\n", theta1 );
  printf( "\n" );


  printf( "In binary sense, \n" );
  printf( " theta0 = " );
  printf_double( theta0 );
  printf( "\n" );
  printf( " theta = " );
  printf_double( theta );
  printf( "\n" );
  printf( " theta1 = " );
  printf_double( theta1 );
  printf( "\n" );
  printf( "\n" );

  printf( "Scan through the range (theta0,theta1) in binary sense, we have ...\n" );
  unsigned __int64 sign_bit0, exponent0, fraction0;
  unsigned __int64 sign_bit1, exponent1, fraction1;
  extract_double(theta0, sign_bit0, exponent0, fraction0 );
  extract_double(theta1, sign_bit1, exponent1, fraction1 );

  unsigned __int64 x;
  for( x=fraction0; x<=fraction1; x++ )
  {
    double thetax = get_double(sign_bit0,exponent0,x);
    printf( " sin(%20.18lf) = %21.18lf\n", thetax, sin(thetax) );
  }
  printf( "\n" );

  printf( " (i.e.\n" );
  for( x=fraction0; x<=fraction1; x++ )
  {
    double thetax = get_double(sign_bit0,exponent0,x);
    printf( " sin(%20.18lf) = %25.18le\n", thetax, sin(thetax) );
  }
  printf( " )\n" );
}
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/1/15 下午 01:12:59
>想了一想, 這也會理的, PI 是無理數, 以 double precision floating point 表達,
>只可能是一個近似值. sin( PI的近似值 ), 不是 0, 也是情理之中的事.
基本上不是無理數的關係。
浮點表示法本來就是差不多先生,所以會有單精度和雙精度,以不表示大差不多還是小差不多。
一個0.0001在浮點數的儲存,小數部份會是100000...,指數部份會是3。
也就是說會把小數點後面的0全移到指數,所以正規的浮點表示法,小數部份,第一個位數一定是1 ,所以是不會有0這個數的。
那0怎麼辦?0在浮點數裡是一個特殊數(指數和小數部份全為0,因為小數第一個位數不是1所以不是正規數)
你可以指派一個0到浮數,但正規數的運算,是不會出現0的,只有接近0... 差不多是0吧,本來浮點數就是差不多先生,不要太計較。
作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2170 | 人氣 89850 | 評價 10100 | 評價/貼文 4.65 | 送出評價 79 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/1/15 下午 02:33:32
>>想了一想, 這也會理的, PI 是無理數, 以 double precision floating point 表達,
>>只可能是一個近似值. sin( PI的近似值 ), 不是 0, 也是情理之中的事.

>基本上不是無理數的關係。
>浮點表示法本來就是差不多先生,
> ...
> ... 正規數的運算,是不會出現0的,只有接近0... 差不多是0吧,本來浮點數就是差不多先生,不要太計較。

^^" 不會吧. sin(0)的運算結果 不就正正是 0 了嗎?

另外呢... 為啥我會 "計較" 這事嘛... 因為我手上正在寫的程式, 經常都需要跟它打交道的.
差不多雖是無奈, 但就算是差不多也好, 也得是 受控+足夠準確的差不多.

作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/1/15 下午 04:13:06
>^^" 不會吧. sin(0)的運算結果 不就正正是 0 了嗎?
我不是說0在浮點數是一個特殊數。
特殊數都是被指派,不是運算的結果。
如困你指派一個0.000........1到一個浮點數,編譯器發現數值小到超過精度,就會指派0到浮點數。
同樣運算結果,運算式(可能)判斷超過精度能表示的,就會把結果指派成0或其它特殊數(NaN)。
當運算結果是0時,一定是最後指派進去的,不是正規運算的結果。
浮點數的特殊數還有無限大,無限小。
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/1/15 下午 04:16:43
喔,可能沒回答到你的問題,你的測試運算,都沒有超過精度所能表示的,所以不會指派0到結果。
sin(0)因為引數己經指派為特殊數0了,在運算時,會特別處理(不同編譯器處理可能有所不同)。
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/1/15 下午 04:26:28
>另外呢... 為啥我會 "計較" 這事嘛
連續怕的現實世界,是沒有絕對準確這回事。
例如你給的零件設計圖,誤差給正負零,工廠是做不出來的。
所以你的程式只是預算一個所需的精度,然後去取捨(四捨五入之類)。
double浮點數或許己超出你所要的精度,在你的精度範圍取拾掉多餘的精度,你就會得到0了。
作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2170 | 人氣 89850 | 評價 10100 | 評價/貼文 4.65 | 送出評價 79 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/1/16 上午 12:26:32
>>另外呢... 為啥我會 '計較' 這事嘛
>連續怕的現實世界,是沒有絕對準確這回事。
>例如你給的零件設計圖,誤差給正負零,工廠是做不出來的。
>所以你的程式只是預算一個所需的精度,然後去取捨(四捨五入之類)。
>double浮點數或許己超出你所要的精度,在你的精度範圍取拾掉多餘的精度,你就會得到0了。

精度需求, 就似解像度. 320x240 的 VCD, 曾幾何時, 也是可以接受的. 或是說, 把你
論述的主角, 換成 32bit floating point, 豈不是可以把 64bit floating point 解釋為無用之物?

^^" 總之呢, 我知道我在幹什麼的. 又或是說, 因何我的程式會需要考慮精度問題也好,
一樓所說的, 也是挺有趣呀. 我也只是打著 "挺有趣 分享一下" 去貼這文的.

就好像 一樓的這個問題 ...
"數算所有在PI附近 的 double precision floating point 數值,
sin( 這些數值 ) 會是多少呢? 會不會有一個 滄海遺珠, 可以令 sin(x) 是 0 呢?"

我估你大概也不曾想過這麼無聊的事吧. ( ^^ 是的, 我猜想 )


> 喔,可能沒回答到你的問題,你的測試運算,都沒有超過精度所能表示的,所以不會指派0到結果。

Mmm... 你能夠找到一個 PI附近 的 double precision floating point 數值 x , 令 sin(x) 等於 0 嗎?
有的話, 願聞其詳.
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/1/16 下午 06:09:38
>精度需求, 就似解像度. 320x240 的 VCD, 曾幾何時, 也是可以接受的.
不是,精度比較像誤差。其誤差度是和數值大小成正比。
也就是說數值越大它的誤差也越大,較大的數值誤差到幾百幾萬都是可能的。

>或是說, 把你論述的主角, 換成 32bit floating point, 豈不是可以把 64bit floating point 解釋為無用之物?
不解何以這樣推論?
當需求的精度超過32 bits時,就只能用64 bits來解決;
64 bits精度也不夠用時,而沒有更高精度floating point可以用時,就自能自製更高精度的實數儲存器。
也沒有用,能不能用,要看應用場合精度的需求。

>^^" 總之呢, 我知道我在幹什麼的. 又或是說, 因何我的程式會需要考慮精度問題也好,
>一樓所說的, 也是挺有趣呀. 我也只是打著 "挺有趣 分享一下" 去貼這文的.
我也是分享為何這樣的道理而己啊!或許比較沒趣吧,呵呵..

>就好像 一樓的這個問題 ...
>"數算所有在PI附近 的 double precision floating point 數值,
>sin( 這些數值 ) 會是多少呢? 會不會有一個 滄海遺珠, 可以令 sin(x) 是 0 呢?"
>我估你大概也不曾想過這麼無聊的事吧. ( ^^ 是的, 我猜想 )
浮點數是個差不多先生,我曾在別的論壇花了不少篇幅詳述(但論壇關了,文章找不到了)。
對於你的問題,或許我針對它,但其結果和我認知的是一樣的,所以並不意外。不會覺得無聊,但不會覺得有趣(因為不意外)

> 喔,可能沒回答到你的問題,你的測試運算,都沒有超過精度所能表示的,所以不會指派0到結果。

>Mmm... 你能夠找到一個 PI附近 的 double precision floating point 數值 x , 令 sin(x) 等於 0 嗎?
>有的話, 願聞其詳.
不同的編譯器可能有不同的結果。這涉及到運算過成也會有精度的問題,可能會在你想要的x逼近sin(0)時被拾棄掉一部份數值。那你就在那個編譯器試不出你要的x。
反之若編譯器的浮點運算可以算到一個結果逼近0但精度超出浮點數的精度範圍,那結果就會指派成0。
在這種預知的兩個可能,去試編譯器,感覺...沒什麼興趣。
不只是0,浮點數有無限個無法表示的數值,例如0.9,浮點數是無法"精確"表示的。
0還有個特殊數可以用,這些無法表示的實數也無替代方案。若你想要某一個運算式(例如9/10)可以得到精確的0.9,那是永遠得不到的。
就算你問那有沒有一個接近9的數字可除以10以後可以得到0.9的結果?答案也是"沒有"。
浮點數的應用,一定要有差不多的觀念去使用。
例如下面的判斷式,或許在邏輯上沒有錯,但在浮點數的觀點卻是錯誤的程式:
if (a==1.345){}//a是浮點變數
正確要這麼寫:
if (a<(1.345+t)||a<(1.345-t))//t是容許誤差範圍
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/1/16 下午 06:20:51
不好意思,太多錯字了,上篇丟棄,看這篇訂正的:

>精度需求, 就似解像度. 320x240 的 VCD, 曾幾何時, 也是可以接受的.
不是,精度比較像誤差。其誤差度是和數值大小成正比。
也就是說數值越大它的誤差也越大,較大的數值誤差到幾百幾萬都是可能的。

>或是說, 把你論述的主角, 換成 32bit floating point, 豈不是可以把 64bit floating point 解釋為無用之物?
不解何以這樣推論?要用那一種,要看應用數值大小和精度需求。
當需求的精度超過32 bits時,就只能用64 bits來解決;
64 bits精度也不夠用時且沒有更高精度floating point可以用時,就只能自製更高精度的實數儲存器。


>^^" 總之呢, 我知道我在幹什麼的. 又或是說, 因何我的程式會需要考慮精度問題也好,
>一樓所說的, 也是挺有趣呀. 我也只是打著 "挺有趣 分享一下" 去貼這文的.
我也是分享為何這樣的道理而己啊!或許比較沒趣吧,呵呵..

>就好像 一樓的這個問題 ...
>"數算所有在PI附近 的 double precision floating point 數值,
>sin( 這些數值 ) 會是多少呢? 會不會有一個 滄海遺珠, 可以令 sin(x) 是 0 呢?"
>我估你大概也不曾想過這麼無聊的事吧. ( ^^ 是的, 我猜想 )
浮點數是個差不多先生,我曾在別的論壇花了不少篇幅詳述(但論壇關了,文章找不到了)。
對於你的問題,或許我沒針對它想過,但其結果和我認知的是一樣的,所以並不意外。不會覺得無聊,但也不會覺得有趣(因為不意外)

> 喔,可能沒回答到你的問題,你的測試運算,都沒有超過精度所能表示的,所以不會指派0到結果。

>Mmm... 你能夠找到一個 PI附近 的 double precision floating point 數值 x , 令 sin(x) 等於 0 嗎?
>有的話, 願聞其詳.
不同的編譯器可能有不同的結果。這涉及到運算過成也會有精度的問題,可能會在你想要的x逼近sin(0)時被拾棄掉一部份數值。那你就在那個編譯器試不出你要的x。
反之若編譯器的浮點運算可以算到一個結果逼近0但精度且超出浮點數的精度範圍,那結果就會指派成0。
在這種預知的兩個可能,去試編譯器,感覺...沒什麼興趣。
不只是0,浮點數有無限個無法表示的數值,例如0.9,浮點數是無法"精確"表示的。
0還有個特殊數可以用,這些無法表示的實數也無表示的替代方案。若你想要某一個運算式(例如9/10)可以得到精確的0.9,那是永遠得不到的。
就算你問,那有沒有一個接近9的數字可除以10以後可以得到0.9的結果?答案也是"沒有"。
你問題的答案,我的回答是:在你的編譯器或在我的編譯器上,或許找得到,但找不到也不意外。你我的編譯器,得到結果也不一定一樣。
浮點數的應用,一定要有差不多的觀念去使用。
例如下面的判斷式,或許在邏輯上沒有錯,但在浮點數的觀點卻是錯誤的程式:
if (a==1.345){}//a是浮點變數
正確要這麼寫:
if (a<(1.345+t)|&&a<(1.345-t))//t是容許誤差範圍
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/1/16 下午 06:27:32
唉,最後一行又改得不乾淨,再訂正
if (a<(1.345+t) && a<(1.345-t))//t是容許誤差範圍
這論壇沒編輯己發出的貼文功能,很不方便。
作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2170 | 人氣 89850 | 評價 10100 | 評價/貼文 4.65 | 送出評價 79 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/1/17 上午 12:11:41

>>^^" 總之呢, 我知道我在幹什麼的. 又或是說, 因何我的程式會需要考慮精度問題也好,
>>一樓所說的, 也是挺有趣呀. 我也只是打著 "挺有趣 分享一下" 去貼這文的.
> 我也是分享為何這樣的道理而己啊!或許比較沒趣吧,呵呵..

能夠博得一句 "呵呵", 令過路人躊躇一下,文章它就滿足了。呵呵^^
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/1/17 上午 12:48:55
>能夠博得一句 "呵呵", 令過路人躊躇一下,文章它就滿足了。呵呵^^
OK 顆顆顆顆...
作者 : turing(Alan)
[ 貼文 68 | 人氣 0 | 評價 300 | 評價/貼文 4.41 | 送出評價 1 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/2/4 上午 07:07:54
從純數學觀點看,sin(丌)=0,sin(丌+δ),δ≠0,得出的值非零,當然無問題。

追溯的問題其實是,電腦上的PI與數學上的丌是否完全相等,數學上的表達是,若PI=丌+δ,這δ是否能等於零?

丌是無理數,浮點數完全表達無理數當然是不可能!

完了?還未曾!

再追問的問題應該是:若以浮點數表達x及sin(x),sin(x)向零收斂是否快於x,即是說lim x->0,sin(x)/x如何表現?

這問題的答案應可回答,在理論層面看,在電腦浮點運算中,sin(PI)歸零的期望是否合理。
作者 : turing(Alan)
[ 貼文 68 | 人氣 0 | 評價 300 | 評價/貼文 4.41 | 送出評價 1 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/2/4 上午 07:17:47
噢!掛一漏萬,最後再追問的問題應該是:

若以浮點數表達x及sin(x),當x靠近丌時,sin(x)向零收斂是否快於x-丌,即是說lim x->丌,sin(x)/(x-丌)如何表現?
作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2170 | 人氣 89850 | 評價 10100 | 評價/貼文 4.65 | 送出評價 79 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/2/4 上午 10:54:45
> 這問題的答案應可回答,在理論層面看,在電腦浮點運算中,sin(PI)歸零的期望是否合理。

把上面的程式帶回家,跟它玩玩遊戲吧。浮點數是可以被了解的,不必一面倒地靠估。有限制,是當然,一樓也沒試著去消除限制 或是 嘗試去找處理方案,它只單是去看清楚情況。是的,是可以看清楚的。
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/2/4 下午 09:36:56
>丌是無理數,浮點數完全表達無理數當然是不可能!
0在浮點數裡也無法正規表達,是用特殊數來表示的。
0.9是有理數,在二進位的小數裡是循環小數,所以....也無法表達(這種有理數有無限個,所以沒有特殊數可以表示)。
超過精度的數字,浮點數也無法精準表達。
在這種情況,去討論數學上的收不收斂,沒有意義。反正總歸一句,浮點數本來就是個差不多先生,不要太苛求。
作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2170 | 人氣 89850 | 評價 10100 | 評價/貼文 4.65 | 送出評價 79 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/2/4 下午 11:29:35

>>丌是無理數,浮點數完全表達無理數當然是不可能!
>0在浮點數裡也無法正規表達,是用特殊數來表示的。
>0.9是有理數,在二進位的小數裡是循環小數,所以....也無法表達(這種有理數有無限個,所以沒有特殊數可以表示)。
>超過精度的數字,浮點數也無法精準表達。
>在這種情況,去討論數學上的收不收斂,沒有意義。反正總歸一句,浮點數本來就是個差不多先生,不要太苛求。

無理數 和 不在浮點數裡的有理數 , 皆不能用浮點數表達.

說無理數不能用浮點數表達, 並沒有說錯啊.
為啥硬要說這說法不對?

是否一併列出 "某些有理數也不能用浮點數表達" 也好,
也不改 無理數不能用浮點數表達的事實.
你是有點撟枉過正了吧.
作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2170 | 人氣 89850 | 評價 10100 | 評價/貼文 4.65 | 送出評價 79 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/2/4 下午 11:47:36
>在這種情況,去討論數學上的收不收斂,沒有意義。反正總歸一句,浮點數本來就是個差不多先生,不要太苛求。

還有, 有浮點數參與的 numerical method, 是多著的呢, 最少最少也有 bisection method, newton's method 和 FEM.
不能以常用函數求解的算式, 就只能用 numerical method 去解, 從數學上去討論收不收斂, 當然也是重要的課題.
還有, 能explicitly以常用函數求解的算式, 其實只是滄海裡的一小小小角, 我隨便列一個 heat transfer 的PDE,
也已經不能用常用函數求解啦.

另外, 就算能用常用函數求解的算式, 就真的跟收不收斂無關了嗎? 這麼, 請問你, 那些常用函數的輸出 又從何而來?

你沒注意的事, 並不等於不重要呢...
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/2/5 上午 12:32:37
>另外, 就算能用常用函數求解的算式, 就真的跟收不收斂無關了嗎? 這麼, 請問你, 那些常用函數的輸出 又從何而來?
應該誤會我的意思,還是我沒沒表達清礎。
我的意思是,浮點數有其精度問題,當運算或結果超過精度時,再收斂下去,輸出的值意義不大,可能也看不收不收斂。
當然在精度以內或可以使用外插法預測會收斂到那一個值,但那不是計算出來的。
至於所謂的輸出,指的是浮點數最後是以十進位表示的嗎?前面一直提過,那是個差不多的數。最後輸出,大部份都有誤差的。
也一直提過,用9除以10的結果,除非有做四拾五入,不然輸出不會得到0.9。
就算你把0.9不經任仃運算,直接指派給一個浮點變數,再把浮點數以十進位輸出,它也不會輸出0.9。
這是因為浮點數除了有精度的問題外,它還有無法表示循環小數的問題。
作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2170 | 人氣 89850 | 評價 10100 | 評價/貼文 4.65 | 送出評價 79 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/2/5 上午 01:02:37
> 至於所謂的輸出,指的是浮點數最後是以十進位表示的嗎?

為啥必需考慮十進制? 十進制是方便 "人" 閲讀, 但十進制不是必需.
用二進制討論, 有何不可? 上文的程式裡, 就是以二進制的方式
去準確數算某範圍裡的所有浮點數.

(... 討論正向著不明方向發展, 我在說的 其實已經是無指向, 只是在漫談而已 ...)
作者 : argus(中年人)
[ 貼文 156 | 人氣 31 | 評價 450 | 評價/貼文 2.88 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/2/5 上午 11:43:39
這不是搞離散數學或DSP時,本來就會面對的基本問題嗎?
以前掌上型計算機都是用4bit CPU,都已經能克服這些問題了!
不喜勿噴
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/2/5 上午 11:47:21
>無理數 和 不在浮點數裡的有理數 , 皆不能用浮點數表達.
>說無理數不能用浮點數表達, 並沒有說錯啊.
>為啥硬要說這說法不對?
我沒說"無理數不能用浮點數表達"是錯的啊!
我只補充浮點數不能表達的不只是無理數。

>為啥必需考慮十進制? 十進制是方便 "人" 閲讀, 但十進制不是必需.
>用二進制討論, 有何不可? 上文的程式裡, 就是以二進制的方式
>去準確數算某範圍裡的所有浮點數.
好像有點在平行軌道裡交談了...:(
談十進制是因為你在2018/2/4 下午 11:47:36談到了"輸出"這件事。
不管電腦裡面存的是幾進位,要輸出就要有表達的格式,進位是表達格式的一種。
所以我回覆你"至於所謂的輸出,指的是浮點數最後是以十進位表示的嗎?",還加了問號呢!
用什麼進位談當然都可以,我不是大部份在說浮點數的格式嗎?
因為你提到了輸出,大部份輸出是以十進位格式沒錯吧,我也只是提到在十進位裡,不是循環小數,但在二進位會變成循環小數。
而循環小數在浮點格式裡,無法正確表達。
作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2170 | 人氣 89850 | 評價 10100 | 評價/貼文 4.65 | 送出評價 79 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/2/5 下午 02:34:47
> 談十進制是因為你在2018/2/4 下午 11:47:36談到了"輸出"這件事。

常用函數的輸出的意思嘛,比方說, double sin( double x ); 的輸出是什麽嘛... 一個 double 呀。


> 因為你提到了輸出,大部份輸出是以十進位格式沒錯吧,我也只是提到在十進位裡,不是循環小數,但在二進位會變成循環小數。

上例的話,輸出的格式是 ... 64 bit floating point number (即是 double)。
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/2/5 下午 03:51:03
>常用函數的輸出的意思嘛,比方說, double sin( double x ); 的輸出是什麽嘛... 一個 double 呀。
>上例的話,輸出的格式是 ... 64 bit floating point number (即是 double)。
我的理解,double只是代表資料型態,和輸出(格式)無關。
這議題應該不值得花這麼多篇幅討論的。回到原議題,
你的意思,因為pi是個無理數,你要從運算得到精準的0做不到是應該的(這是你的意思吧);
從數學觀點,是沒有錯,但若不考慮精度( 精度無限),數學上是可以一直往0逼近。
我只是指出在C裡使用浮點數運算測試,會先被精度卡關而得不到0,而不是因為無理數的關係。
如果不是浮點數精度的問題,你的測試就算得不到0,但可以一直一直...往0逼近,而不是到了某一個值時,就無法再逼近了。
就是這樣而己,如果你還是認為測不出0是因為無理數的關係,就也好吧。誠如你說的,純粹好玩,不值得花那麼多篇幅討論。
作者 : ozzy123(ozzy) 資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4473 | 人氣 37262 | 評價 10900 | 評價/貼文 2.44 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/2/19 下午 04:32:08
若以浮點數表達x及sin(x),當x靠近丌時,sin(x)向零收斂是否快於x-丌,即是說lim x->丌,sin(x)/(x-丌)如何表現?
lim x->丌,sin(x)/(x-丌) = cos(丌) = -1 ; regarding sin(x) as a function and above expression is a derivative of sin(x) at x = 丌 or its slope of sin(x) at x = 丌 is -1.
作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2170 | 人氣 89850 | 評價 10100 | 評價/貼文 4.65 | 送出評價 79 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/2/20 下午 04:12:18
>若以浮點數表達x及sin(x),當x靠近丌時,sin(x)向零收斂是否快於x-丌,即是說lim x->丌,sin(x)/(x-丌)如何表現?
>lim x->丌,sin(x)/(x-丌) = cos(丌) = -1 ; regarding sin(x) as a function and above expression is a derivative of sin(x) at x = 丌 or its slope of sin(x) at x = 丌 is -1.

(... @@? 這家伙在說啥? 在用 google翻譯 把西班牙文翻譯成中文嗎? 詭異... 詭異... ...)
 板主 : simula
 > C++ - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - C++ - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
C++
1 Raymond 13050 
2 青衫 4760 
3 simula 4690 
4 coco 4030 
5 白老鼠(Gary) 3670 
6 ozzy 2540 
7 Ben 2250 
8 Anderson 1960 
9 windblown 1650 
10 Kenny 1560 
C++
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2018 程式設計俱樂部 http://www.programmer-club.com.tw/
0.234375