b97902HW 板


LINE

有一些容易产生误解的地方来解释一下 xD ※ 引述《iForests (森林)》之铭言: : ‧浮点数误差‧ :   用到 double 时是无论如何都得提到浮点数误差的,不过这里只打算乱讲。简单来说 : 是这样,当你放例如 5 在变数里时,电脑有可能存 4.9999999999999999999999999999。 : 原则上是没有差别,但有时候会造成影响。使徒三是个好例子,很多人写一写可能会发现 : 印出来的东西竟然有 -0.000,其原因正是因为变数值为像 -0.00000000000002147483647 : 这种後面接了一些怪东西的值(只是随便打的)。因此输出时认为它不是 0,而是一个很 : 小很小的负数,所以取 3 位小数时印出 -0.000。 这里可能会误导人。虽然原因应该是有一个很小的负数, 但是真的有 -0 这个东西。浮点数格式有 -0 和 +0 :) 我刚才发现 Wiki 还有介绍 xD http://en.wikipedia.org/wiki/%E2%88%920_(number) :   解法方法很简单,我们加一个很小很小又不至於太小的数给它,例如 1e-10。 : -0.00000000000002147483647 : +0.0000000001 : ------------------------------ : 0.00000000009997852516353 :   这样一来,用 %.3lf 印出时,答案就会是 0.000 了。 这地方有一点小问题,请看下面。 : ‧数学函式‧ (使用前需先 #include <math.h>) : 首先,π = 2.0 * acos(0.0) = 3.1415926535897932384626433832795。 : ↑这是确确实实的 0.0 而不是表情符号 :   sin()、cos() 等等函数传入的参数必须使用弪度而非角度,转换方法高中数学课应 : 有提过,总之:弪度 = 角度 * π / 180。 这边似乎有点太理想了 xDDDD 上面这一行丢到编译器去执行 得出来的结果应该是 3.141592653589793115997963468544185161590576171875... (double) 而不是 3.1415926535897932384626433832795... (真的圆周率) 对了,也可以直接用 acos (-1) 喔! : 推 LoganChien:#include <float.h> 之後,你可以用 DBL_MAX 代表极大 09/30 22:40 : → LoganChien:的值(double 可以表示的最大值) 09/30 22:40 : 推 LoganChien:检查二个 double 是否相同,最好用下面的公式,以减少 09/30 22:48 : → LoganChien:意外。﹝误差造成的﹞ 09/30 22:48 : → LoganChien:fabs(a - b) < DOUBLE_PRECISION_EPSILON 09/30 22:49 : → LoganChien:let DOUBLE_PRECISION_EPSILON = 1e-9. 09/30 22:49 以上是用绝对误差来实作,通常也都不会有什麽问题, 不过如果更深入了解 double 的格式的话, 就会知道 double 的误差是相对的而不是绝对的。 意思是说,对於 1000000000 来说 1e-9 的误差比较容易发生, 但对於 0.000001 来说 1e-9 就比较不容易了。 (可参考 http://en.wikipedia.org/wiki/IEEE_754-2008 或是计概应该会教) 事实上「浮点数」在字面上就讲明小数点是「浮动」的 例如,一般我们写成 5000 和 0.0005 的两个数, 就实际上在记忆体中浮点数的储存方法来看, 应该理解成 5 * 10^3 和 5 * 10^-4 比较恰当 所以误差是相对的而不是绝对的 (附注:电脑里面用的是二进位,所以更接近 x * 2^y) 那到底要怎麽去处理浮点数的误差? 这是个很复杂的问题,端看你的目的而定。 以下这篇文章有讲如何比较两个数字是否一样: http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm 另外我在这边提供一个思考的观点, 到底要允许计算中有多大的误差可以用最後的要求来定, 例如这次的作业可能要求小数点以下三位, 如果你估计最後的答案是 1000 附近(我只是举例) 那麽你可能就要让你整个运算的相对误差控制在 0.0000005 以内 (0.5e-6) 或是绝对误差控制在 0.0005 以内 (0.5e-3) 这样子最後印出来时才会和正确(没有误差)的答案比较接近。 运算中的误差传递我相信普物应该有教 xDDD 大致上来说,加法比较不会让误差扩大太快 lol 该讲的讲完了,至於要怎麽写,套一句刘墉的话,「你自己决定吧!」 : → LoganChien:1. 单纯的习惯,我也有看过有人用 1e-8, 1e-10 10/01 00:11 : → LoganChien:2. (印象中) C++ 标准规定 double 最低精确度是 1e-9 10/01 00:12 我相信到这边 1 应该比较清楚了 至於 2 又要花篇幅讲了~ 由於大家学的是 C,加上我没有看过最新 C++0x 的标准 所以在这里我只讲 C99 的状况 C99 的标准後面的 Annex F 有讲说 C 里面的 float, double, long double 和 IEC 60559:1989 (也就是 ANSI/IEEE 754-1985) 如何对应 简单来说,要研究 C 的 double 是怎麽运算的,可以查阅上述标准的 倍精浮点数(double-precision floating point number) 先一下历史和题外话 xD 其实除了 IEEE 754-1985 以外 还有一个 IEEE 854 的标准也在规定浮点数的运算 啊不过最近 IEEE 754-2008 (又称 IEEE 754r... 名称超多 - -|||) 把这两个旧标准都吃掉了 ANSI/IEEE 754-xxxx 和 ISO/IEC 9899:1999 (C99 的标准) 都是要$$$$$的 还好在官网上面可以下载定案前的 "draft" (非正式版,但是跟正式版很接近这样) 而且也有很多依照这些标准写的教学网站,好读好懂又免费! 好,那这些标准到底怎麽规定误差的呢? 就像之前讲的,这些标准有订出 double 在记忆体上应该怎麽储存, 格式会接近这样: (有一些例外的状况请自己看文章:http://en.wikipedia.org/wiki/IEEE_floating-point_standard S 1.XXXXXXXXX * 2^YYYYYYY 例如 + 1.00010100 * 2^(+001011) 每个亮色的地方都要花记忆体储存,而 double 短短 64 bits 就由这三部份所瓜分 S 是正负号(一个 bit 就够了),YYYYY 的长度决定後面的指数部份可以多大多小, 而 XXXXX 的长度决定了精确度,一切的罪孽都是来自 XXXXX 不够长 -v- double 的 YYYYXXXX 都比 float 的 YYYYXXXX 还多位, 所以不仅可以处理比较大的数字,数字也可以存比较多位(误差小)。 double 的 XXXX 只有 52 位~ 电脑要把运算结果塞回记忆体中时,很可能就会产生误差! 预设的误差处理方法是二进位的「四舍六入五取双」 大致上是取最接近运算答案的表示方法~ 讲到这边,聪明的大家应该就可以知道, 单纯因为 double 储存格式产生的相对误差大约是 2^-5X (有些小细节我不想讲了 orz) 大约是 10^-15 ~ 10^-16 左右 (也就是十进位下大约有 15 位 xD 大家可以看前面的圆周率大约第几位开始爆炸) 至於 C++ 我猜应该也是用同样的标准玩的 有兴趣欢迎补充 xDDDD -- 我在 P2 也有版喔 xD 同 ID 喵~ --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.30.39 ※ 编辑: Favonia 来自: 140.112.30.39 (10/02 21:31)
1F:推 godgunman:是大彼得耶!!!! 10/02 21:41
2F:推 godgunman:话说, 今天助教时间有讲IEEE-754 10/02 21:47
※ 编辑: Favonia 来自: 140.112.30.39 (10/02 21:52)
3F:推 wolfdigit: 大彼得好威!!! 10/02 21:54
4F:推 ming1053: 大彼得好威!!! 这篇讲的好清楚 10/02 22:04
5F:推 ckclark:-0今天忘了讲 10/02 22:17
6F:推 iForests:有神快拜!!!!!(拜) 10/02 22:17
7F:推 scan33scan33: 大彼得好威!!!(拜) 10/02 22:46
8F:推 anfranion:传说中的大彼得(仰望) 10/02 22:53
9F:推 rewqrewwq:感谢学长指教!(拜) 10/02 23:03
10F:推 Bakaking:娘子,快跟牛魔王出来见上帝! 10/02 23:53
11F:→ benck:推一个 字好多喔 要慢慢消化 10/03 00:07
12F:推 sa072686:有神快拜!!!!!(拜) 10/03 00:22
13F:推 LoganChien:拿香跟拜!(拜) 10/03 00:23
14F:→ LoganChien:获益良多! 10/03 00:25
※ 编辑: Favonia 来自: 140.112.30.39 (10/03 02:07)
15F:推 pigalan: 大彼得好威!!!(拜) 10/03 22:24







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:WOW站内搜寻

TOP