怎样识别一个数是单精度数还是双精度数? 请问如何判断C语言中的某个变量是单精度的还是双精度的???

\u663e\u5361\u7684\u53c2\u6570\u91cc\u600e\u4e48\u770b\u662f\u53cc\u7cbe\u5ea6\u8fd8\u662f\u5355\u7cbe\u5ea6\uff1f

\u53ef\u4ee5\u7528\u8f6f\u4ef6\u201cAIDA64\u201d\u67e5\u770bGPU\u7684\u5355\u3001\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u8fd0\u7b97\u80fd\u529b\uff0c\u5177\u4f53\u65b9\u6cd5\u5982\u4e0b\uff1a
1\u3001\u5982\u4e0b\u56fe\uff0c\u641c\u7d22\u201caida64\u201d\uff0c\u70b9\u51fb\u8fdb\u5165\u5b98\u7f51\uff1a

2\u3001\u5982\u4e0b\u56fe\uff0c\u8fdb\u5165\u5b98\u7f51\u4e0b\u8f7d\u9875\u9762\uff0c\u4e0b\u8f7d\u7b2c\u4e8c\u6392\u7684\u8d44\u6e90\uff08ZIP\u683c\u5f0f\u3001\u7ea2\u8272\u6807\uff09\uff0c\u70b9\u51fb\u540e\u9762\u7684\u201cDownload\u201d\u5f00\u59cb\u4e0b\u8f7d\uff1a

3\u3001\u5982\u4e0b\u56fe\uff0c\u4e0b\u8f7d\u540e\u76f4\u63a5\u89e3\u538b\uff0c\u5f97\u5230\u6587\u4ef6\u5939\uff0c\u6587\u4ef6\u5939\u4e2d\u6709\u4e00\u4e2a\u56fe\u6807\u5982\u4e0b\uff0c\u53cc\u51fb\u5373\u53ef\u6253\u5f00aida64\uff0c\u7eff\u8272\u7248\uff0c\u65e0\u9700\u5b89\u88c5\u76f4\u63a5\u4f7f\u7528\uff1a

4\u3001\u5982\u4e0b\u56fe\uff0c\u6253\u5f00aida64\u540e\uff0c\u70b9\u51fb\u62ac\u5934\u83dc\u5355\u680f\u7684\u201c\u5de5\u5177\u201d\u2192\u201cGPGPU\u6d4b\u8bd5\u201d\uff1a

5\u3001\u5982\u4e0b\u56fe\uff0c\u70b9\u51fb\u5e95\u90e8\u7684\u201cstart benchmark\u201d\u5f00\u59cb\u6d4b\u8bd5\uff0c\u8010\u5fc3\u7b49\u5f85\u81ea\u52a8\u6d4b\u8bd5\u5b8c\u6210\uff0c\u663e\u793a\u7ed3\u679c\u3002\u4f8b\u5982\u4e0b\u56fe\u4e2d\u82f1\u7279\u5c14\u6838\u5fc3\u663e\u5361HD630\u6d4b\u5f97\u7ed3\u679c\u2014\u2014\u5355\u7cbe\u5ea6\u6d6e\u70b9\uff08single\u2026\u2026\uff09\u662f382.7 GFLOPS\uff0c\u53cc\u7cbe\u5ea6\u6d6e\u70b9\uff08double\u2026\u2026\uff09\u662f95.14 GFLOPS\uff1a

\u6709\u58f0\u660e\u554a\uff0c\u53d8\u91cf\u58f0\u660e\u4f1a\u544a\u8bc9\u4f60\u662f\u5355\u7cbe\u5ea6\u8fd8\u662f\u53cc\u7cbe\u5ea6float\u5355\uff0cdouble\u53cc

单精度和双精度数值类型最早出现在C语言中(比较通用的语言里面),在C语言中单精度类型称为浮点类型(Float),顾名思义是通过浮动小数点来实现数据的存储。这两个数据类型最早是为了科学计算而产生的,他能够给科学计算提供足够高的精度来存储对于精度要求比较高的数值。但是与此同时,他也完全符合科学计算中对于数值的观念:

当我们比较两个棍子的长度的时候,一种方法是并排放着比较一下,一种方法是分别量出长度。但是事实上世界上并不存在两根完全一样长的棍子,我们测量的长度精度受到人类目测能力和测量工具精度的限制。从这个意义上来说,判断两根棍子是否一样长丝毫没有意义,因为结果一定是False,但是我们可以比较他们两个哪个更长或者更短。这个例子很好地概括了单精度/双精度数值类型的设计初衷和存在意义。

基于上述认识,单精度/双精度数值类型从一开始设计的时候,就不是一个准确的数值类型,他只保证在他这个数值类型的精度之内是准确的,精度之外则不保证,比方说,一个数值5.1,很可能存储在单精度/双精度数值中的实际值是5.100000000001或者5.09999999999999。导致这个现象的原因我们可以通过两种方式来解释:

简单的解释方法:

你可以尝试在任何一个控件的属性面板中,设定他的宽度为:3.2CM,当你输入完毕后,你会发现值自动变成了3.199cm,无论你怎么改,你都无法输入3.200CM,因为实际上在电脑中存储的并不是CM为单位的数值,而是“缇”为单位的数值,而“缇”和CM之间的比值,是个很难被除尽的数,因此你输入完毕后,电脑自动转换成了最接近的“缇”值,然后再转换成厘米显示到属性面板上,这一乘一除,两次四舍五入,误差就出来了。单精度/双精度也是类似的原理,其实在二进制存储的时候,单精度/双精度都采用了类似相近分数的方法,而这样的存储是不可能做到准确的。

深入的解释方法:

让我们来看看我们存储到数字介质中的单精度/双精度值到底是怎么样的,我们使用如下代码对单精度类型进行一个解剖:

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Public Sub floatTest()
Dim dblVar As Single

dblVar = 5.731 / 8
dblOutput dblVar

dblVar = dblVar * 2
dblOutput dblVar

dblVar = dblVar * 2
dblOutput dblVar

dblVar = dblVar * 2
dblOutput dblVar

dblVar = dblVar * 2
dblOutput dblVar

dblVar = dblVar * 2
dblOutput dblVar

End Sub

Public Sub dblOutput(ByVal dblVar As Single)
Dim bytVar(3) As Byte
Dim i As Integer, j As Integer
Dim strVar As String

CopyMemory ByVal VarPtr(bytVar(0)), ByVal VarPtr(dblVar), 4
strVar = dblVar & ": "
For i = 3 To 0 Step -1
For j = 7 To 0 Step -1
strVar = strVar & (bytVar(i) And 2 ^ j) / 2 ^ j
Next j
strVar = strVar & " "
Next i
Debug.Print strVar

End Sub
运行后我们得到输出结果(输出格式为高位左,低位右):

.716375: 00111111 00110111 01100100 01011010
1.43275: 00111111 10110111 01100100 01011010
2.8655: 01000000 00110111 01100100 01011010
5.731: 01000000 10110111 01100100 01011010
11.462: 01000001 00110111 01100100 01011010
22.924: 01000001 10110111 01100100 01011010
这里,我们把单精度类型转化成了二进制数据输出,这里我们看到,虽然这六个数字完全不同,但是他们的二进制存储惊人地相似,我们看到红色标记部分,每次都是加1,事实上,单精度数据类型使用从高位开始第1位作为正负标记位(绿色),第2位到第9位,是一个跨字节的有符号字节类型数据,这个数值决定了小数点移动的方向和位数(红色),第10位到32位保存一个整数(蓝色)在存储过程中,电脑首先把输入的值不断移位(乘除2)直到这个数的整数部分占用了全部24位的整数位,然后把移动的位数写入浮点部分(红色),而移位后的结果写入整数部分(蓝色和绿色),小数部分则舍弃。求值的时候则是反向过程,先根据正负位和整数位求值,然后根据红色部分的整数来进行移位(乘除2的次方),最终才是我们得到的单精度数值。双精度数值也是同样原理,只是位数更多而已。

通过解剖单精度数值的二进制存储格式,我们可以清楚看到,实际上单精度/双精度的存储,都要通过乘法和除法,其中必有舍入,如果恰好你的数值在除法中被舍入了,那么你赋的初值就很可能与你最终存储的值不完全相同,其中的微小差异,并不与单精度/双精度的设计目标相违背。

当我们在数据库中或者VBA代码中使用一个单精度/双精度数值的时候,也许你从界面上看不到区别,但是在实际的存储中,这个差别却真真切切地就在那里,当你对其进行相等比较的时候,系统只是简单地作二进制的比较,界面上无法体现的微小差异,在二进制比较面前却无处遁形,于是,你的等于比较返回了一个意料之外的False。
参考资料:百度

  1. 数后加上字母f,如 2.3f、1.0f 等此类是单精度浮点数(float) 。

  2. 数直接写出的数字,如 2.3、1.0 等此类是 double 型的。
    使用double声明的变量和常数是双精度浮点数。
    使用float声明的变量和常数是单精度浮点数。

  C 语言浮点数默认是 double 型(双精度浮点数)的。



位数

  • 濡備綍鍒ゆ柇涓涓鍊鏄崟绮惧害杩樻槸鍙绮惧害?
    绛旓細渚嬪锛屽湪Python涓紝鎴戜滑鍙互妫鏌ヤ竴涓肩殑'dtype'灞炴ф潵鏌ョ湅鍏舵暟鎹被鍨嬨绗簩娈碉細\n鍒ゆ柇涓涓兼槸鍗曠簿搴﹁繕鏄弻绮惧害涓昏鐪嬪叾鏁版嵁绫诲瀷銆傚湪澶у鏁扮紪绋嬭瑷涓紙濡侰++, Java, Python绛夛級锛屽崟绮惧害鍜屽弻绮惧害鍒嗗埆鐢眆loat鍜宒ouble琛ㄧず銆備緥濡傦紝鍦≒ython涓紝鍙互閫氳繃type()鍑芥暟鏉ュ垽鏂竴涓肩殑绫诲瀷銆傚綋鎴戜滑鍦ㄤ竴涓暟鍊...
  • 鎬庢牱璇嗗埆涓涓暟鏄崟绮惧害鏁拌繕鏄弻绮惧害鏁?
    绛旓細鏁扮洿鎺ュ啓鍑虹殑鏁板瓧锛屽 2.3銆1.0 绛夋绫绘槸 double 鍨嬬殑銆浣跨敤double澹版槑鐨勫彉閲忓拰甯告暟鏄弻绮惧害娴偣鏁般備娇鐢╢loat澹版槑鐨勫彉閲忓拰甯告暟鏄崟绮惧害娴偣鏁銆侰 璇█娴偣鏁伴粯璁ゆ槸 double 鍨嬶紙鍙岀簿搴︽诞鐐规暟锛夌殑銆
  • 鍙湁涓浣嶅皬鏁鎬庝箞鍒ゆ柇鍗曠簿搴﹀弻绮惧害
    绛旓細姝ょ被鎯呭喌涓嬪彲浠ユ寜浠ヤ笅鏂规硶鍒ゆ柇绮惧害鐨勫崟鍙岋細鍗曠簿搴︽诞鐐规暟浣跨敤32浣嶏紙4瀛楄妭锛夊瓨鍌锛屽弻绮惧害娴偣鏁颁娇鐢64浣嶏紙8瀛楄妭锛夊瓨鍌ㄣ傝繖涓ょ娴偣鏁扮殑瀛樺偍闀垮害涓嶅悓锛屽洜姝ゅ彲浠閫氳繃鍒ゆ柇灏忔暟鐨勪綅鏁板拰鑼冨洿鏉ョ‘瀹氬叾绫诲瀷銆傚崟绮惧害娴偣鏁扮殑鏈夋晥鏁板瓧浣嶆暟绾︿负7浣嶏紝鍥犳灏忔暟鍦ㄨ〃绀哄崟绮惧害娴偣鏁版椂鐨勮寖鍥村簲璇ュ湪绾β10^38鏁伴噺绾т箣闂淬傚...
  • 鎬庢牱鍒ゆ柇VB涓暟鍊煎瀷鏄崟绮惧害鍨杩樻槸鍙绮惧害鍨?濡:23.456鍗,3.1416鍗...
    绛旓細2涓渶鏄庢樉鐨勫尯鍒氨鍦ㄤ簬鍗曠簿搴﹀彧绮剧‘鍒7浣锛岃屽弻绮惧害绮剧‘鍒15浣 鎴戜笉鐭ラ亾浣犳槸浠庡摢鐪嬫潵鐨勮12.34567杩欎笉鏄崟绮惧害锛屼笉杩囨垜鍙互鍛婅瘔浣狅紝杩欎釜鍙簿纭埌7浣嶇殑鏁板氨鏄崟绮惧害锛屽綋鐒跺畠鍚屾椂涔熷彲浠ュ弻绮惧害锛
  • 濡備綍鍖哄垎鍗曞弻绮惧害?
    绛旓細鍙岀簿搴﹁兘琛ㄧず鐨勬暟鏇村箍锛屽崟绮惧害鐩稿杈冪獎銆傜簿搴︽槸琛ㄧず瑙傛祴鍊间笌鐪熷肩殑鎺ヨ繎绋嬪害銆傛瘡涓绉嶇墿鐞嗛噺瑕佺敤鏁板艰〃绀烘椂锛屽繀椤诲厛瑕佸埗瀹氫竴绉嶆爣鍑嗭紝骞堕夊畾涓绉嶅崟浣 (unit)銆傝繖绉嶆爣鍑嗙殑鍒跺畾锛岄氬父鏄牴鎹汉浠浜庢墍瑕佹祴閲忕殑鐗╃悊閲忕殑璁よ瘑涓庝簡瑙o紝骞朵笖瑕佽冭檻杩欐爣鍑嗘槸鍚﹀鏄撳鍒讹紝鎴栨祴閲忕殑杩囩▼鏄惁瀹规槗鎿嶄綔绛夊疄闄呴棶棰樸傚湪姝e父...
  • 鎬庢牱纭畾涓涓鏌愪釜鏁板鏄崟绮惧害杩樻槸鍙绮惧害
    绛旓細1銆佺涓姝ワ紝鎵撳紑Matlab骞跺湪蹇嵎宸ュ叿鏍忎腑鍗曞嚮鈥滄柊寤鸿剼鏈濋夐」锛岃涓嬪浘锛岃浆鍒颁笅闈㈢殑姝ラ銆2銆佺浜屾锛屽畬鎴愪笂杩版楠ゅ悗锛屽彲浠ヤ娇鐢╥mopen鍑芥暟瀵瑰浘鍍忔墽琛屾墦寮鎿嶄綔锛屽苟涓旇鍑鏁拌繕闇瑕佹寚瀹涓涓鍏冪礌缁撴瀯浣滀负绗簩涓弬鏁帮紝浠ュ強瑕佽鍙栫殑鍥惧儚浠ュ強鏄剧ず鍓嶅悗鐨勬瘮杈冿紝鍏蜂綋浠g爜瑙佷笅鍥撅紝杞埌涓嬮潰鐨勬楠ゃ3銆佺涓夋锛屽畬鎴愪笂杩...
  • 鍗曠簿搴娴偣鏁颁笌鍙岀簿搴娴偣鏁扮殑鍖哄埆鏄浠涔?
    绛旓細鍗曠簿搴﹀瀷鍜鍙岀簿搴鍨嬬殑鍖哄埆鍦ㄤ簬瀹冧滑鐨勭簿纭▼搴︿笉涓鏍凤紝涔熷氨鏄皬鏁伴儴鍒嗙殑鏈夋晥浣嶆暟涓嶄竴鏍枫鍗曠簿搴︽暟锛坒loat鍨嬶級鍦32浣嶈绠楁満涓瓨鍌ㄥ崰鐢4瀛楄妭锛屼篃灏辨槸32浣嶏紝鏈夋晥浣嶆暟涓7浣嶏紝灏忔暟鐐瑰悗6浣嶏紱鍙岀簿搴︽暟锛坉ouble鍨嬶級鍦32浣嶈绠楁満涓瓨鍌ㄥ崰鐢8瀛楄妭锛屼篃灏辨槸64浣嶏紝鏈夋晥浣嶆暟涓16浣嶏紝灏忔暟鐐瑰悗15浣嶃傛瘮濡3....
  • 鏄惧崱鐨勫弬鏁伴噷鎬庝箞鐪鏄弻绮惧害杩樻槸鍗曠簿搴?
    绛旓細鍙互鐢ㄨ蒋浠垛淎IDA64鈥濇煡鐪婫PU鐨勫崟銆鍙岀簿搴娴偣杩愮畻鑳藉姏锛屽叿浣撴柟娉曞涓嬶細1銆佸涓嬪浘锛屾悳绱⑩渁ida64鈥濓紝鐐瑰嚮杩涘叆瀹樼綉锛2銆佸涓嬪浘锛岃繘鍏ュ畼缃戜笅杞介〉闈紝涓嬭浇绗簩鎺掔殑璧勬簮锛圸IP鏍煎紡銆佺孩鑹叉爣锛夛紝鐐瑰嚮鍚庨潰鐨勨淒ownload鈥濆紑濮嬩笅杞斤細3銆佸涓嬪浘锛屼笅杞藉悗鐩存帴瑙e帇锛屽緱鍒版枃浠跺す锛屾枃浠跺す涓鏈変竴涓鍥炬爣濡備笅锛屽弻鍑诲嵆鍙墦寮...
  • 鍗曠簿搴鍜鍙岀簿搴鐨勫尯鍒鏄浠涔?
    绛旓細鍗曠簿搴涓鍙岀簿搴鐨勫尯鍒細1銆佸崟绮惧害锛屼篃灏辨槸 float 锛屽湪 32 浣嶆満鍣ㄤ笂鐢 4 涓瓧鑺傛潵瀛樺偍鐨勶紱鑰屽弻绮惧害double鏄敤 8 涓瓧鑺傛潵瀛樺偍鐨勩2锛屽崟绮惧害鍜屽弻绮惧害鍦ㄨ绠楁満涓殑琛ㄧず鏍煎紡铏戒竴鏍凤紝浣嗙敱浜庝綅鏁板瓨鍌ㄤ綅涓嶅悓锛屼粬浠兘琛ㄧず鐨勬暟鍊肩殑鑼冨洿灏变笉鍚岋紝涔熷氨鏄兘鍑嗙‘琛ㄧず鐨勬暟鐨勪綅鏁板氨涓嶅悓銆
  • 娴偣鏁鍗曠簿鏁鍜屽弻绮炬暟鐨勫尯鍒湁鍝簺?
    绛旓細1锛鍗曠簿搴锛屼篃灏辨槸 float 锛屽湪 32 浣嶆満鍣ㄤ笂鐢 4 涓瓧鑺傛潵瀛樺偍鐨勶紱鑰鍙岀簿搴double鏄敤 8 涓瓧鑺傛潵瀛樺偍鐨勶紝杩欐槸浠栦滑鏈鏈川鐨勫尯鍒2锛岀敱浜庡瓨鍌ㄤ綅涓嶅悓锛屼粬浠兘琛ㄧず鐨勬暟鍊肩殑鑼冨洿灏变笉鍚岋紝涔熷氨鏄兘鍑嗙‘琛ㄧず鐨勬暟鐨勪綅鏁板氨涓嶅悓銆3锛屽崟绮惧害灏忔暟鐐瑰悗闈㈠叡鑳界簿纭埌7浣嶅皬鏁般傚弻绮惧害鍙簿纭埌15浣嶅皬鏁般
  • 扩展阅读:扫一扫识别数量 ... 5.0为啥是双精度 ... 3.0是单精度还是双精度 ... 精确度为0.1保留几位 ... 电表0.5和0.5s级差多少 ... 单精度为什么不直接用双精度 ... 2.3是单精度还是双精度 ... 单精度双精度举个例子 ... 怎么判断单精度还是双精度 ...

    本站交流只代表网友个人观点,与本站立场无关
    欢迎反馈与建议,请联系电邮
    2024© 车视网