str2double with long string seems to give wrong answer

조회 수: 9 (최근 30일)
Philip Masding
Philip Masding 2024년 2월 29일
댓글: VBBV 2024년 3월 1일
Run in MATLAB on line
str='6879331413876961408';
num=str2double(str);
fprintf('%i',num)
6879331413876961280
6879331413876961280
  댓글 수: 2
Stephen23
Stephen23 2024년 2월 29일
"str2double with long string seems to give wrong answer"
No, it gives the correct answer: it gives you the DOUBLE value that is closest to that specified in the string.
Lets phrase it a different way: can you show us a DOUBLE value that is closer that specified in the string? (hint: no)
Lets try it right now:
str = '6879331413876961408';
num = str2double(str);
hex = num2hex(num)
hex = '43d7de12de40149c'
next_higher = hex2num('43d7de12de40149d');
next_lower = hex2num('43d7de12de40149b');
fprintf('%.0f\n',next_lower,num,next_higher)
6879331413876960256 6879331413876961280 6879331413876962304
We can see that 1408 is closer to 1280 than either 0256 or 2304.
So your hypothesis that "str2double with long string seems to give wrong answer" is easily demonstrated to be incorrect. What is much much more likely is that you have not considered the implications of using finite precision binary floating point numbers.
Dyuman Joshi
Dyuman Joshi 2024년 2월 29일
Description from str2double documentation - "X = str2double(str) converts the text in str to double precision values."
There's a significance of underlined part. You should read about it.
Also, note the data type of the output obtained in Walter's answer.

댓글을 달려면 로그인하십시오.

채택된 답변

Walter Roberson
Walter Roberson 2024년 2월 29일
format long g
str = '6879331413876961408';
num = sscanf(str, '%ld')
num = int64
6879331413876961408

추가 답변 (2개)

John D'Errico
John D'Errico 2024년 2월 29일
편집: John D'Errico 2024년 2월 29일
Do you appreciate that str2double will convert the number to a DOUBLE PRECISION number? Of course it must, as why would it convert to something other than a double? MATLAB does not by default work in arbitrarily high precision. If it did, it would be relatively as slow as molasses on too many computations. And then people (maybe even you) would be complaining at how slow it was. So MATLAB uses doubles for almost all computations, unless you specifically use some other class. (syms, for example could store that number, or my own VPI or HPF classes.)
What is the maximum integer a double can store? (Exactly)
flintmax
ans = 9.0072e+15
which is 2^53-1, in case you care. Numbers large than flintmax, but less than realmax will see only the top (approximately) 16 digits retained. Anything below that becomes computational garbage. Is your number larger than flintmax?
6879331413876961408/flintmax
ans = 763.7592
So it is too large, by a factor of almost 1000. Note that the 3 least significant digits were wrong. Should that be a surprise here if the number if too large by a factor of 1000 to fit into a double exactly?
If you truly needed to store that number in some other class and you don't want to use the alternatives I mentioned, it turns out tht int64 or uint64 could do it exactly. For example:
6879331413876961408 < intmax('int64')
ans = logical
1
uint64(6879331413876961408)
ans = uint64 6879331413876961408

VBBV
VBBV 2024년 2월 29일
fprintf('%d',num)
  댓글 수: 6
Dyuman Joshi
Dyuman Joshi 2024년 2월 29일
@VBBV, you can not use a format specifier for str2double. The input (if convertible to a double precision value) will always be converted to a double precision value (otherwise NaN will be the output).
VBBV
VBBV 2024년 3월 1일
str='6879331413876961408';
% num=str2double(str)
fprintf('%s',str)
6879331413876961408
As @Dyuman Joshi mentioned that using str2double and/or str2num functions will result in double precision values which are limited by significant 16 digits. @Philip Masding you can get same value if you use format specfifier for string %s

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Data Type Conversion에 대해 자세히 알아보기

제품


릴리스

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by