Discussion:
請問 C 語言的精準度
(时间太久无法回复)
none
2004-10-30 10:05:55 UTC
Permalink
我用 C 語言算1/3,結果得到0.333333。
以下是我的程式:
#include<stdio.h>
int main()
{
double a=1.0/3;
printf("%lf\n",a);
return 0;
}
-----
我覺得這個 C 程式所計算的精準度只能達到小數點後第6位。
R 的的精準度可以達到小數點後第7位。
Matlab 7 的的精準度可以達到小數點後第14位。
請問 C 語言程式的精準度還可以再提高嗎?最高精準度是多少?
是否要利用math.h?

--
╭┼ Origin:  暨大電機˙漂浮電子  bbs.ee.ncnu.edu.tw 
┼┘ Author: tame 從 140.127.114.222 發表
none
2004-10-30 14:12:40 UTC
Permalink
Post by none
我覺得這個 C 程式所計算的精準度只能達到小數點後第6位。
你printf寬度不給寬一點當然就只有六位啦
我把printf後的小數位提高到16位數,發現他的四捨五入有問題。
#include<stdio.h>
int main()
{
double a=1.0/7;
printf("%.16lf\n",a);
return 0;
}
結果是0.1428571428571428。
我用Windows 計算機算1/7=0.14285714285714285714285714285714
比較:
0.1428571428571428
0.14285714285714285714285714285714

可見這個值在 C 應該是 0.1428571428571429。
請問如何避免這個四捨五入的錯誤?
我覺得小數位後16位數已經是精準的極限了,再高就會有誤差。
請問還能夠把精準度提升到小數位後20位數而不會有誤差嗎?
 


--
╭┼ Origin:  暨大電機˙漂浮電子  bbs.ee.ncnu.edu.tw 
┼┘ Author: tame 從 140.127.114.222 發表
none
2004-10-30 14:33:36 UTC
Permalink
我發現C到小數點後16位數"偶而"四捨五入會有問題。
而 Matlab 7 最高的精準度是 Numeric format 為 long e 的情況,
也是小數點後16位數,可是 Matlab 7 四捨五入完全沒有問題。
所以建議跑模擬用 Matlab 7 會比較精準。


--
╭┼ Origin:  暨大電機˙漂浮電子  bbs.ee.ncnu.edu.tw 
┼┘ Author: tame 從 140.127.114.222 發表
unsigned(NULL)
2004-10-30 15:11:04 UTC
Permalink
�ڧ�printf�᪺�p�Ʀ촣����16���ơA�o�{�L���|�ˤ��J�����
�@
�N�کҪ�,C�x�s�Ȫ��̫��@�쪺�ɭԬO�L�����˥h��

�ƭȹB���W�o�ػ~�t�s�˦��~�t.
--
�~���v�j���T�C�զⱡ�g���s�w �� Origin : snow.ice.ntnu.edu.tw
�u���� 140.122.77.49����w �� From : 218-161-76-58.dynamic.hinet.net
系統組的雜工 vs JOL
2004-10-30 15:43:42 UTC
Permalink
:  
: 就我所知,C儲存值的最後一位的時候是無條件捨去的
: 數值運算上這種誤差叫捨位誤差.
可是我剛試寫了一小段..
顯示出的是
0.333333
0.666667
所以應該是四括五入沒錯吧!?
你寫的程式是因為用了 printf 搭配 %f 顯示
所以才會輸出四捨五入的結果
還是因為編譯器的問題..我是用BCB
原始碼如下~
#include<stdio.h>
int main(void)
{
printf("%f\n%f",1/3.0,2/3.0);
^^^^^^^^^^
getch();
return 0;
}
--
 @, ●秘密情人● (bbs.cse.ttu.edu.tw) 
~\ ◆ Post From: 61-70-137-117.adsl.static.giga.net.tw ◆
系統組的雜工 vs JOL
2004-10-30 16:04:10 UTC
Permalink
Post by none
我發現C到小數點後16位數"偶而"四捨五入會有問題。
所謂有效位數是總位數,而不是小數點後的位數

#include <stdio.h>

int main(){
printf("%.20f\n",1234567890.123456789);
printf("%.16f\n",1234567890.123456789);

printf("%.20f\n",1.234567890123456789);
printf("%.16f\n",1.234567890123456789);

return 0;
}
======
output
======
1234567890.12345670000000000000
1234567890.1234567000000000
1.23456789012345670000
1.2345678901234567

超過部份直接被丟掉,沒有四捨五入

--
 @, ●秘密情人● (bbs.cse.ttu.edu.tw) 
~\ ◆ Post From: 61-70-137-117.adsl.static.giga.net.tw ◆
unsigned(NULL)
2004-10-30 16:05:26 UTC
Permalink
:  
: 就我所知,C儲存值的最後一位的時候是無條件捨去的
: 數值運算上這種誤差叫捨位誤差.
可是我剛試寫了一小段..
顯示出的是
0.333333
0.666667
所以應該是四括五入沒錯吧!?
還是因為編譯器的問題..我是用BCB
原始碼如下~
#include<stdio.h>
int main(void)
{
printf("%f\n%f",1/3.0,2/3.0);
~~~~~~~~~~~~~~~~~~~
printf是將值列印出來的位數%f的話是小數點後六位,會自動四捨五入
我指的是變數儲存的位數
double precision最多只能存到小數點十六位,所以第十七位以後就會無條件捨去
single precision 可以到小數點八位(我不大記得幾位了)
第九位就會被捨去
沒有經變數存取直接1/3.的話,位數好像是就是看compiler內定大小而定吧
getch();
return 0;
}
--
╭╢師大資訊。白色情迷╟┬─ ⊙ Origin : snow.ice.ntnu.edu.tw
├╨→ 140.122.77.49←╜╰─ ☆ From : 218-161-76-58.dynamic.hinet.net
系統組的雜工 vs JOL
2004-10-30 16:53:50 UTC
Permalink
Post by 系統組的雜工 vs JOL
======
output
======
1234567890.12345670000000000000
1234567890.1234567000000000
1.23456789012345670000
1.2345678901234567
超過部份直接被丟掉,沒有四捨五入
我印象中 visual c++ 編出來的程式碼好像都會直接把後面搞成 0,
所以之前我學弟一直問我為什麼 VC++ 跟 gcc 編出來的跑數據會不一樣。
但是我剛才的程式也是用 gcc 編譯出來執行的結果
看得出來它也把後面都搞成 0 了

--
 @, ●秘密情人● (bbs.cse.ttu.edu.tw) 
~\ ◆ Post From: 61-70-137-117.adsl.static.giga.net.tw ◆
系統組的雜工 vs JOL
2004-10-30 17:10:47 UTC
Permalink
Post by unsigned(NULL)
printf是將值列印出來的位數%f的話是小數點後六位,會自動四捨五入
我指的是變數儲存的位數
double precision最多只能存到小數點十六位,所以第十七位以後就會無條件捨去
single precision 可以到小數點八位(我不大記得幾位了)
第九位就會被捨去
沒有經變數存取直接1/3.的話,位數好像是就是看compiler內定大小而定吧
直接寫 1/3.0 這種 expression
計算結果會被當作 double
所以有效位數也就知道了

--
 @, ●秘密情人● (bbs.cse.ttu.edu.tw) 
~\ ◆ Post From: 61-70-137-117.adsl.static.giga.net.tw ◆
電風扇
2004-10-30 17:28:30 UTC
Permalink
Post by 系統組的雜工 vs JOL
Post by 系統組的雜工 vs JOL
======
output
======
1234567890.12345670000000000000
1234567890.1234567000000000
1.23456789012345670000
1.2345678901234567
超過部份直接被丟掉,沒有四捨五入
我印象中 visual c++ 編出來的程式碼好像都會直接把後面搞成 0,
所以之前我學弟一直問我為什麼 VC++ 跟 gcc 編出來的跑數據會不一樣。
但是我剛才的程式也是用 gcc 編譯出來執行的結果
看得出來它也把後面都搞成 0 了
--
 @, ●秘密情人● (bbs.cse.ttu.edu.tw) 
~\ ◆ Post From: 61-70-137-117.adsl.static.giga.net.tw ◆
VC++用的編譯器就是gcc阿= =
所以結果當然一樣....
如果真的要做到四捨五入
那請自己寫判斷式吧~^^

--
◢◤ ◢◥ ◢◣ ◢◤   嘉義女中 寧園小築  ﹒∴` ▁▂▃▄▅▆▄▃
▉▁ ◥◢ ◥◣ █◣ Origin * cgsh.twbbs.org‥︰∵▃▄▆ ..﹒‥︰∵ 
 ◥◤ ◥◤ ◥◤ ◤◥ Author ◆ 211-74-252-115.adsl.dynamic.seed ▆▄▃▂ˍ
不要再reject啦~!
2004-10-30 19:17:59 UTC
Permalink
※ 引述《***@ptt.cc (*Ptr)》之銘言:
: ※ 引述《***@kkcity.com.tw (㊣λπ-βθ自由貿易協定)》之銘言:
: : 有這種事嗎?
: 這到底是不是真的?
: 那dev C++的核心咧?
:  
Dev-cpp是以gcc為核心.它的網頁清楚提到 (http://www.bloodshed.net/devcpp.html)
Bloodshed Dev-C++ is a full-featured Integrated Development Environment (IDE)
for the C/C++ programming language. It uses Mingw port of GCC
(GNU Compiler Collection) as it's compiler. Dev-C++ can also be used in
combination with Cygwin or any other GCC based compiler.

--
╔═════════════════════════════════════╗
║ Though thou loved her as thyself, ║ 雖然你愛她,把她當自己一樣, ║
║ As a self of purer clay, ║ 把她當作一個較純潔的自己, 值 ║
║ Tho' her parting dims the day, ║ 雖然她離去了使日月無光, ◣ 日 ║
║ Stealing grace from all alive, ║ 使一切生物都失去了美麗, ◢█ 生 ║
║ Heartily know, When half-gods go, ║ 你應當知道半人半神走了, ◥█◤ : ║
║ The gods arrive. ║ 神就來了。 ██ ▃ ▃ 22 ║
╚═════════════════════════════════════╝

--
╭──── bbs.csie.mcu.edu.tw ───────────╮ 走吧!!! ╔═══╗
│ The First IPv6 Ready BBS ~~~*歡迎光臨*~~~ │ ● ● ║ 神話 ║
│ From: 218-168-99-60.dynamic.hinet.net  >/*~*> ╚═══╝
╰──────────────────────────╯ || |﹨ ﹊
系統組的雜工 vs JOL
2004-10-31 02:35:02 UTC
Permalink
Post by 系統組的雜工 vs JOL
但是我剛才的程式也是用 gcc 編譯出來執行的結果
看得出來它也把後面都搞成 0 了
1234567890.12345671653747558594
1234567890.1234567165374756
1.23456789012345669043
1.2345678901234567
Using built-in specs.
Configured with: FreeBSD/i386 system compiler
Thread model: posix
gcc version 3.4.2 [FreeBSD] 20040728
嗯 看來就算都用 gcc 也可能有不同結果
那我也不知道為什麼了
因為我的確也是用 gcc
D:\Dev-Cpp>gcc --version
gcc (GCC) 3.3.1 (mingw special 20030804-1)
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

還是說 dev-cpp 提供的 library 有什麼差異嗎?

--
 @, ●秘密情人● (bbs.cse.ttu.edu.tw) 
~\ ◆ Post From: 61-70-137-117.adsl.static.giga.net.tw ◆
系統組的雜工 vs JOL
2004-10-31 02:42:37 UTC
Permalink
Post by 電風扇
VC++用的編譯器就是gcc阿= =
所以結果當然一樣....
在 VC 目錄底下的 bin 目錄裡面
有個 CL.EXE
以下是 VC6 之 CL 的版本
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]

--
 @, ●秘密情人● (bbs.cse.ttu.edu.tw) 
~\ ◆ Post From: 61-70-137-117.adsl.static.giga.net.tw ◆
none
2004-10-31 05:27:49 UTC
Permalink
Post by 系統組的雜工 vs JOL
但是我剛才的程式也是用 gcc 編譯出來執行的結果
看得出來它也把後面都搞成 0 了
1234567890.12345671653747558594
1234567890.1234567165374756
1.23456789012345669043
1.2345678901234567
Using built-in specs.
Configured with: FreeBSD/i386 system compiler
Thread model: posix
gcc version 3.4.2
因為會有這樣的誤差,所以建議這樣用16位元的有效數字:
#include<stdio.h>
int main()
{
double a=1234567890.1234566;
printf("%16f\n",a);
return 0;
}
output:1234567890.123457
但如果a是1234567890.12345659
則output:1234567890.123456
但是瑕不掩瑜,勉強可以接受這誤差。
但在論文模擬最好不要用,以達完美無缺。
論文數值模擬可以用兩種方法:
1. 之前網友講的:
自己寫計算程式應該就沒問題,1*10/7=1,

10%7=3,3*10/7=4,30%7=2,2*10/7。。。

看要算到小數後幾位,就重覆幾次,一個個丟入字串,要四捨五入的話,

就再算出最後一位的下一位,判斷它是否大於等於五。
2. 用 Matlab 7。但我有一些疑惑,就是輸入123456789012345.54555,
它會顯示1.234567890123456e+014。我覺得它應該
顯示1.234567890123455e+014才對,因為1.234567890123455e+014比
1.234567890123456e+014還靠近123456789012345.54555。
不知道這是 Matlab 7 的bug還是我觀念錯誤?還請各位網友指教。

--
╭┼ Origin:  暨大電機˙漂浮電子  bbs.ee.ncnu.edu.tw 
┼┘ Author: tame 從 140.127.114.222 發表
继续阅读narkive:
Loading...