Re: [問題] 取小數點

看板C_and_CPP作者 (藍影)時間14年前 (2011/05/30 06:29), 編輯推噓1(1011)
留言12則, 5人參與, 最新討論串2/2 (看更多)
※ 引述《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

05/30 10:53, , 1F
取double的整數部份可以用floor()
05/30 10:53, 1F

05/30 13:51, , 2F
謝謝樓上建議 ^_^
05/30 13:51, 2F

05/30 16:05, , 3F
應該是用modf
05/30 16:05, 3F

05/30 18:14, , 4F
假如你要打10的n次方的話 直接ne就好了呀...
05/30 18:14, 4F

05/30 18:17, , 5F
比方說10的6次方就打6e就好了呀...
05/30 18:17, 5F

05/30 18:41, , 6F
而且是fmod...
05/30 18:41, 6F

05/30 22:37, , 7F
http://0rz.tw/KIme4 <==modf. 我只是要回答取整數
05/30 22:37, 7F

05/31 18:58, , 8F
恩...我考混了...
05/31 18:58, 8F

05/31 19:47, , 9F
05/31 19:47, 9F

05/31 23:41, , 10F
XD
05/31 23:41, 10F

06/01 18:04, , 11F
x = x - (int)x 這樣不就好了?
06/01 18:04, 11F

06/01 18:08, , 12F
=D= t大第3種寫過了 XD
06/01 18:08, 12F
文章代碼(AID): #1DuiZJBz (C_and_CPP)
討論串 (同標題文章)
本文引述了以下文章的的內容:
問題
2
10
完整討論串 (本文為第 2 之 2 篇):
問題
2
10
文章代碼(AID): #1DuiZJBz (C_and_CPP)