Double precision: Why does fprintf print "extra" wrong non zero digits?

9 ビュー (過去 30 日間)
Joseph Ragan
Joseph Ragan 2024 年 3 月 11 日
編集済み: James Tursa 2024 年 3 月 11 日
As shown in this code, matlab will print incorrect digits to more than 16 places of precision. Where do the numbers for the "extra" digits come from?
clear;clc
a=1/6;
fprintf('\n58digits\t%60.58f\n',a)
%result
%58digits 0.1666666666666666574148081281236954964697360992431640625000
%%%question
%by default matlab is double precision for all numbers
%what is the source of the "extra" digits 574148081281236954964697360992431640625
%after the 0625, all digits will be zero
  1 件のコメント
Joseph Ragan
Joseph Ragan 2024 年 3 月 11 日
James Tursa,
Thank you! I understand now. This coverter also helped me confirm the info you provided (that fprint is printing the entire ieee 754 double.
ultimatesolver.com/en/ieee-754
Regards
Joe

サインインしてコメントする。

採用された回答

James Tursa
James Tursa 2024 年 3 月 11 日
編集済み: James Tursa 2024 年 3 月 11 日
The "extra" digits that look incorrect to you are simply the result of doing an exact conversion of the actual floating point binary bit pattern that is stored to decimal. They are meaningful in that sense. But the values are only significant to about 16 decimal digits. E.g.,
a=1/6;
fprintf('\n58digits\t%60.58f\n',a-eps(a))
58digits 0.1666666666666666296592325124947819858789443969726562500000
fprintf('\n58digits\t%60.58f\n',a)
58digits 0.1666666666666666574148081281236954964697360992431640625000
fprintf('\n58digits\t%60.58f\n',a+eps(a))
58digits 0.1666666666666666851703837437526090070605278015136718750000
eps(a)
ans = 2.7756e-17
The three numbers printed are all exact conversions, so the digits mean something in that sense. Those long decimal digits are the equivalent of what is actually stored internally for the number in binary. 1/6 cannot be represented exactly in IEEE double precision, so the closest number to it is picked for the internal representation and what is displayed with fprintf() is an exact conversion of that number. The two closest numbers to a that can be represented in IEEE double precision format are about 2.7756e-17 away from it. I.e., there is only about 16 decimal digits of precision in that number.
Some numbers can be represented exactly, e.g.,
fprintf('\n58digits\t%60.58f\n',1/8)
58digits 0.1250000000000000000000000000000000000000000000000000000000
But others cannot, such as 1/6.
CAVEAT: Windows MATLAB R2017a and earlier used a different background library for fprintf( ) and related functions. In those versions, you would not get these extra exact conversion digits printed. It is only on later Windows MATLAB versions that use an updated library where you get these digits printed. To my knowledge, the non-Windows MATLAB versions always used libraries that printed these digits. For these earlier Windows MATLAB versions, you would need to use a different function to get those digits, e.g.,
  1 件のコメント
Joseph Ragan
Joseph Ragan 2024 年 3 月 11 日
James
Thank you! The explaination that fprintf was printing the entire number stored was great.
I had a misconception about the spacing of the numbers that could be stored. Your explanation and an online conversion calculator helped me clarify my understanding.
Others might find it useful
ultimatesolver.com/en/ieee-754
Regards
Joe

サインインしてコメントする。

その他の回答 (1 件)

Florian Bidaud
Florian Bidaud 2024 年 3 月 11 日
編集済み: Florian Bidaud 2024 年 3 月 11 日
By default, MATLAB uses 16 digits of precision. The rest can come from intermediate format conversion errors inside fprintf, due to the difference between the asked precision and the format of the number.
This is described here:
for example, intermediate operations and conversions within the single function:
format long
x = 0.2
x =
0.200000000000000
y = single(0.2)
y = single
0.2000000
z = x - y
z = single
-2.9802323e-09
If you need more than 16 digits of precision, you can use:
  1 件のコメント
Joseph Ragan
Joseph Ragan 2024 年 3 月 11 日
移動済み: Dyuman Joshi 2024 年 3 月 11 日
Florian,
I don’t understand. If the number 0.1666666666666666 is stored as a double, how would fprintf interpret that as a bigger number even if prompted for increased precision. I would expect the increased precision from fprintf to poplulate with zeros.
Regards
Joe

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeLogical についてさらに検索

製品


リリース

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by