Can I make printf format floats like C++ streams - printf

I am comparing the output of two programs, one C the other C++, using diff, so the output must be identical.
Is there any way to printf a double so that it is formatted as though it was printed using << mydouble.
I am currently using printf("%g",mydouble)
Here are some examples of the differences:
c: 3.24769e-05 c++: 3.2477e-05
c: 0.0026572 c++: 0.00265721
Interestingly the scientific notation has more digits in c, and the decimal notation has more in c++.

You can solve this by using the format specifiers in C.
For example, say you would like to print out only 3 places after the decimal, you could make your printf like so:
printf("%.3lf", dub);
With a value of double dub = .0137; the output would be 0.014
This would fix the issue with your 2nd case if you want more precision printed you could write:
printf("%.8lf", dub);
Your output for double dub = 0.00265721; would then be 0.00265721
The case for %g works the same way except the number on the left is included in the calculation. If you wanted the C++ version (the lesser precision I assume) then your code would look like this:
double dub = .0000324769;
printf("%.5g", dub);
Which yields 3.2477e-05

Related

Formatting in Raku

I have written a function that outputs a double, upto 25 decimal
places. I am trying to print it as a formatted output from Raku.
However, the output is incorrect and truncated.
See MWE:
my $var = 0.8144262510988963255087469;
say sprintf("The variable value is: %.25f", $var)
The above code gives The variable value is: 0.8144262510988963000000000 which is not what is expected.
Also, this seems weird:
my $var = 0.8144262510988963255087469;
say $var.Str.chars; # 29 wrong, expected 27
I tested the same in C:
#include <stdio.h>
int main() {
double var = 0.8144262510988963255087469;
printf("The variable value is: %.25lf \n", var);
return 0;
}
However, it works fine. Given the identical nature of sprintf and printf, I expected this C example to work in Raku too. Seems like %lf is not supported.
So is there a workaround to fix this?
I think this is actually a bug in how Rat literals are created. Or at least as WAT :-).
I actually sort of expect 0.8144262510988963255087469 to either give a compile time warning, or create a Num, as it exceeds the standard precision of a Rat:
raku -e 'say 0.8144262510988963255087469'
0.814426251098896400086204416
Note that these are not the same.
There is fortunately an easy workaround, by creating a FatRat
$ raku -e 'say 0.8144262510988963255087469.FatRat'
0.8144262510988963255087469
FWIW, I think this is worthy of creating an issue
From your question:
I have written a function that outputs a double, upto 25 decimal places.
From google:
Double precision numbers are accurate up to sixteen decimal places
From the raku docs :
When constructing a Rat (i.e. when it is not a result of some mathematical expression), however, a larger denominator can be used
so if you go
my $v = 0.8144262510988963255087469;
say $v.raku;
#<8144262510988963255087469/10000000000000000000000000>
it works.
However, do a mathematical expression such as
my $b = $a/10000000000000000000000000;
and you get the Rat => Num degradation applied unless you explicitly declare FatRats. I visualise this as the math operation placing the result in a Num register in the CPU.
The docs also mention that .say and .put may be less faithful than .raku, presumably because they use math operations (or coercion) internally.
Sorry to be the bearer of bad news, but 10**25 > 2 **64, but what you report as an issue is correct & (fairly) well documented behaviour given the constraints of double precision IEEE P754.

How to print a number with number of fixed characters in Smalltalk/Pharo

Actual task: I want to print the matrix (of my own implementation) in humanly readable format. As a pre-requisite, I figured I need to be able to specify "fit the number representation into X characters". I found #printShowingDecimalPlaces: and #printPaddedWith:to: in Float and Integer classes (the first method is in more general Number class). Individually, they work, but the former works on fractional part only and the the latter on part before fractional, e.g.:
10.3 printPaddedWith: Character space to: 5.
"' 10.3'"
-10.3 printPaddedWith: Character space to: 5.
"' -10.3'"
10.3 printShowingDecimalPlaces: 3.
"'10.300'"
Also, their action on very large (or equally small numbers) in scientific form is not ideal:
12.3e9 printShowingDecimalPlaces: 3.
"'12300000000.000'"
12.3e9 printPaddedWith: Character space to: 5.
"' 1.23e10'"
So, I would like something like Common Lisp's (FORMAT T "~10g" 12.3d9) or C's printf("%10g", 12.3e9), that (a) restricts the whole width to 10 characters and (b) chooses the most suitable format depending on the size of the number. Is there something like this in Pharo?
For versatile printing options, I suggest loading NumberPrinter package from
http://ss3.gemstone.com/ss/NumberPrinter/
(FloatPrinter fixed) digitCount: 2; print: 10.3.
-> '10.30'
I did not try it in recent Pharo versions though.
EDIT:
Ah, but I see no format for handling exponents multiple of 3, maybe you would have to create a subclass for such format.
EDIT:
Or I missunderstood: you don't want it to print as '12.3e9' but rather '1.23e10'? note that apart significand digitCount, you need extra size for at worst 1 for sign + 1 for fraction separator + 1 for exponent letter + 1 for exponent sign + 3 for exponent (worst case for double precision floating point).
The more or less equivalent to g format would be something like this:
(FloatPrinter freeFormat)
totalWidth: 13; "size of the generated string"
digitCount: 6; "number of significant figures"
print: -12.3e-205.
->' -1.23e-204'

How to print formatted float in obj-c?

How to print a float in Objective-C as, for example, 3.45 instead of 3.45555555555?
Try formatting the float like this:
NSLog(#"%.2f", myFloat);
The % sign means this will be replaced by the corresponding argument following (myFloat). The .2 means 2 decimal places, and f means a float datatype.
Take a look here for more detail.
Objective-C's NSLog is very similar to C's printf, with the main exceptions being that you must use an Objective-C string literal (#"…") and you should use %# for Objective-C strings (NSStrings) rather than %s, which is for "Plain C strings".
Depends on how you're printing it. If you want to show it in a GUI (which is probably the common case for Cocoa and Cocoa Touch apps), use an NSNumberFormatter and set it to have two decimal places. If you're printing it through NSLog() or printf(), you'd use a format specifier along the lines of "%.2f".

Showing decimals of a variable with sprintf in MATLAB

I don't understand the next thing that happens using the sprintf command.
>> vpa(exp(1),53)
ans =
2.7182818284590455348848081484902650117874145507812500
>> e = 2.7182818284590455348848081484902650117874145507812500
e =
2.7183
>> sprintf('%0.53f', e)
ans =
2.71828182845904550000000000000000000000000000000000000
Why does sprintf show me the number e rounded instead of the number and I kept at the first place?
Variables are double precision by default in MATLAB, so the variable e that you create is limited to the precision of a double, which is about 16 digits. Even though you entered more digits, a double doesn't have the precision to accurately represent all those extra digits and rounds off to the nearest number it can represent.
EDIT: As explained in more detail by Andrew Janke in his answer to this follow-up question I posted, the number you chose for e just happens to be an exact decimal expansion of the binary value. In other words, it's the exactly-representable value that a nearby floating-point number would get rounded to. However, in this case anything more than approximately 16 digits past the decimal point is not considered significant since it can't really be represented accurately by a double-precision type. Therefore, functions like SPRINTF will automatically ignore these small values, printing zeroes instead.

printing floating point numbers in D

It's been quite a while since I last used D Programming Language, and now I'm using it for some project that involves scientific calculations.
I have a bunch of floating point data, but when I print them using writefln, I get results like: 4.62593E-172 which is a zero! How do I use string formatting % stuff to print such things as 0?
Right now I'm using a hack:
if( abs(a) < 0.0000001 )
writefln(0);
else
writefln(a);
it does the job, but I want to do it using the formatting operations, if possible.
UPDATE
someone suggested writefln("%.3f", a) but the problem with it is that it prints needless extra zeros, i.e. 0 becomes 0.000 and 1.2 becomes 1.200
Can I make it also remove the trailing zeros?
Short answer: This can't be done with printf format specifiers.
Since D uses the same formatting as C99's vsprintf(), you find your answer in this thread: Avoid trailing zeroes in printf()
Try something like
writefln("%.3f", a);
Federico's answer should work, for more information check the format specifiers section.
I see you are currently using Phobos, however what you are trying to do is supported in Tango.
Stdout.formatln("{:f2}", 1.2);
will print "1.20"