Hello,
I have encountered an issue while trying to convert reals to strings.
Here is my initial issue: I have a program that stores different values of a variable, does some stuff in Mata and uses these values in a Stata command.
When there is no leading digit, I deduced that the closest value to 0 is 10^-307
The next step was to check what format in strofreal() allowed me to get back the right value after the conversion.
But after brute forcing it, it seems that a width of 24 handles most of the cases
But there is still a difference for 10^19 and 10^20 and no width seem to correct it.
Worse:
Hence, I have few questions:
Mael Astruc--Le Souder
I have encountered an issue while trying to convert reals to strings.
Here is my initial issue: I have a program that stores different values of a variable, does some stuff in Mata and uses these values in a Stata command.
- I have the exact value as a real in Mata
- I convert it as a string using the strofreal() function
- I concatenate my Stata command with the sprintf() function
Code:
1.0 + 10^-15 == 1.0 // false 1.0 + 10^-16 == 1.0 // true 0.1 + 10^-17 == 0.1 // false 0.1 + 10^-18 == 0.1 // true 0.01 + 10^-17 == 0.01 // false 0.01 + 10^-18 == 0.01 // true
Code:
10^-307 == 0 // false 10^-308 == 0 // true
Code:
strtoreal(strofreal(10^-307, "%22.0g")) == 10^-307 // false strtoreal(strofreal(10^-307, "%23.0g")) == 10^-307 // true
Code:
for (i = -308; i <= 308; i++) { x_num = 10^i x_str = strofreal(x_num, "%24.0g") x_back = strtoreal(x_str) are_same = (x_back == x_num) if (are_same == 0) { i x_num x_str x_back x_num - x_back } }
Worse:
- this does not happen on every run
- other values do not work anymore with larger widths such as 10^21, 10^22, 10^23
Code:
strofreal(10^19, "%23.0g") // 1.0000000000000000e+19 strofreal(10^19, "%24.0g") // 1000000000000000000.\x17 strofreal(10^19, "%25.0g") // 1000000000000000000.\x17 strofreal(10^19, "%26.0g") // 1000000000000000000.\x17 sprintf("%s", strofreal(10^19, "%23.0g")) // 1.0000000000000000e+19 sprintf("%s", strofreal(10^19, "%24.0g")) // 1.00000000000000000e+19 sprintf("%s", strofreal(10^19, "%25.0g")) // 1.000000000000000000e+19 sprintf("%s", strofreal(10^19, "%26.0g")) // 1000000000000000000.8\x0c\x1c
- Does my approach to inject back the value in the Stata command makes sense ?
- Is there a known width that would suffice ?
- What is the issue with 10^19 and 10^20 ?
- How can I handle it ?
Mael Astruc--Le Souder
Comment