Negative zero when writing to file

19 ビュー (過去 30 日間)
Shaun
Shaun 2020 年 3 月 30 日
コメント済み: Walter Roberson 2020 年 3 月 31 日
So I have some MATLAB code that is writing out data to a CSV file. The CSV file is an output of test vectors being used by a C++ program to determine pass/fail of an algorithm implementation with test vectors generated by MATLAB. Part of what my code is generating is outputs of a conversion from spherical coordinate to Cartesian coordinate, so I am computing r*sin(theta)*cos(phi). When theta is 0, as you would expect, the equation evaluates to 0. However, if 90 degrees < phi < 270 degrees (i.e. in the second quadrant or third quadrant, where cosine would be negative), MATLAB returns a negative 0. If I have MATLAB print the value, I get a positive 0 and no indication that it is negative, but when I write the number to my CSV file, I end up getting -0.000. I am using fprintf(fileId, "%10.10e", res) to get my result to the file because I need to be able to control the precision of the output and writetables() would not always give accurate enough precision for the test vectors.
This causes problems because if C++ reads in a -0 for some functions, it treats it as a different kind of error case, so I don't want MATLAB writing these -0.000.
I can confirm that it is being stored in memory as a negative 0 by doing num2hex(), which returns 8000000000000000 instead of 0000000000000000. Is there anything I can do to help prevent this from occurring? I need my answers to be negative if they turn out to be negative, so I can't wrap with an absolute value, but negative 0 feels like it should be incorrect in this scenario since multiplication by 0 is defined as 0 and sin(0) = 0.
value = 10.0*sin(0.0)*cos(3*pi/2);
num2hex(value) = '8000000000000000'
fprintf(fileId,"10.4e", value) >> -0.000
value = 10.0*sin(0.0)*cos(0);
num2hex(value) = '0000000000000000'
fprintf(fileId,"10.4e", value) >> 0.000

回答 (2 件)

Walter Roberson
Walter Roberson 2020 年 3 月 30 日
value = value + 0;
  1 件のコメント
Walter Roberson
Walter Roberson 2020 年 3 月 31 日
value = 10.0*sinpi(0.0)*cospi(3/2);
>> num2hex(value)
ans =
'0000000000000000'

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


dpb
dpb 2020 年 3 月 30 日
The problem is one of rounding/floating point precision. The cos(3*pi/2) is mathematically zero, indeed, but it isn't quite so in floating point representation where pi isn't exact...
>> format short
>> value = ([sin(0.0) cos(3*pi/2) sin(0.0)*cos(3*pi/2)])
value =
1.0e-15 *
0 -0.1837 0
>>
I don't think there's a way to prevent MATLAB from returning the sign, only suggestion I would have would entail either testing the output string or to test the quadrant during the calculation and set values within 2 or 3 eps() identically to zero after the calculation before the write.
Either, unfortunately, is going to take some overhead...
This could be worth a Support Request to see if TMW would have a better workaround suggestion.

カテゴリ

Help Center および File ExchangeGet Started with MATLAB についてさらに検索

製品

Community Treasure Hunt

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

Start Hunting!

Translated by