[爆卦]浮點數小數點是什麼?優點缺點精華區懶人包

為什麼這篇浮點數小數點鄉民發文收入到精華區:因為在浮點數小數點這個討論話題中,有許多相關的文章在討論,這篇最有參考價值!作者tropical72 (藍影)看板C_and_CPP標題Re: [問題] 取小數點時間Mon M...

浮點數小數點 在 雙橡教育 Instagram 的最讚貼文

2021-09-16 10:14:13

【新學期新氣象,限動模板寫下你的新目標!】⁣⁣ ⁣⁣ 還記得今年年初的自己嗎?你是不是默默地期許自己能夠在新的一年培養規律作息與讀書習慣,並成功地兼顧課業與社團的平衡?⁣⁣ ⁣⁣ 半年匆匆地過去了,新學期開始步入軌道了,小編想帶著大家一起回顧上學期的目標,並同時為下學期做些簡單的準備,讓大家能夠在接...


※ 引述《s4399》之銘言:
: EX:n=1.000056
: 我該如何利用printf("%.f",n)的指令來取得56這兩個數值?
: 或是這麼說……
: 如果a/b=1.0026595698...
: 我該如何只取出1.00後面的數據丟給n
: 又如果我只要取出2659這四位數的話,該怎麼做?

先假設變數名稱

typedef unsigned long long uint64;
double d1 = 1.000056; // 10^6
double d2 = 1.0026595698; // 10^10
double d3 = 1.123456789012345; // 10^15

1. 先去看 十三戒之十一 ,連結一起看的話大概 30~60 mins 左右。

>> a/b=1.0026595698

由於這句話,認為你是在計算過程中要求得小數後之非零數字,

2. 一般數字小的時候可確實可這樣做

d1 = d1 - (int)d1; /* 先只取小數部份 */
uint64 i1 = d1*1000000 - (uint64)d1*1000000ULL; /* 再將小數化為整數 */

因雙精度浮點數之 matissa 54 bits, 有效位數約 15.22 位,
用 unsigned int 去存,會爆掉的機率太大了,於是直接給 64 bits 去存

接著其它的 d2, d3, 分別以上述做法,去乘 10^10, 10^15 來做。
其中若用 unsigned int 去接,d3 必爆 (d2 也快了),這裡可再去試試。

優點:速度快
缺點:調整後容易有誤差、要指定該魔數數字。

3. 較普遍性的作法

我不是很清楚為何要把小數點後的零全都拿掉,即使要調整,
我認為也是該保留零較佳,這樣到時要比較大小、再合併回浮點數時也較方法,
於是可以把這個寫成副函式呼叫

uint64 get_matissa(double x)
{
double x_float = x - (int)x;
return x_float * 1000000000000000ULL; /* 精度 15.22 */
}

優點:呼叫方便、魔數數字只要用一次
缺點:調整後仍有誤差。

4. 較準確的作法

我認為較準確應是下面這種作法

uint64 get_matissa2(double x)
{
uint64 ret, t;
char buffer[50], Zero[20];
sprintf(buffer, "%.15lf", x);
sscanf(buffer, "%*llu%[^1-9]%llu", Zero, &ret);
return ret;
}

會用 .15lf 是因 double 有效位數約 15.22 位, 第 16 位開始便沒參考價值。

先用 sprintf 到一 buffer 裡面去,再直接 parse ,
但這麼做效能會「特慢」, 因 sprintf 、sscanf 都是速度超慢的函式,
但這麼做拿到的數值應是最準的。

5. 其它方式

有種方式還沒實做,但也不確定可行 - 直接去分析 IEEE 754 欄位,
直接抽出小數部份。之所以「不確定」,是因我不甚確定每套 compiler
是否都從 IEEE 754 (據悉,部份 compiler 在數值極小的時候會有所「手腳」),
若不是的話那這部份就可以不用做。


--
YouLoveMe() ? LetItBe() : LetMeFree();

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.73.222
littleshan:取double的整數部份可以用floor() 05/30 10:53
tropical72:謝謝樓上建議 ^_^ 05/30 13:51
angleevil:應該是用modf 05/30 16:05
firejox:假如你要打10的n次方的話 直接ne就好了呀... 05/30 18:14
firejox:比方說10的6次方就打6e就好了呀... 05/30 18:17
firejox:而且是fmod... 05/30 18:41
angleevil:http://0rz.tw/KIme4 <==modf. 我只是要回答取整數 05/30 22:37
firejox:恩...我考混了... 05/31 18:58
angleevil:搞 05/31 19:47
firejox:XD 05/31 23:41
xatier:x = x - (int)x 這樣不就好了? 06/01 18:04
xatier:=D= t大第3種寫過了 XD 06/01 18:08

你可能也想看看

搜尋相關網站