Using printf to align doubles by decimal not working - c

I want to print doubles so that the decimals line up. For example:
1.2345
12.3456
should result in
1.2345
12.3456
I have looked everywhere, and the top recommendation is to use the following method (the 5s can be anything):
printf(%5.5f\n");
I have tried this with the following (very) simple program:
#include <stdio.h>
int main() {
printf("%10.10f\n", 0.523431);
printf("%10.10f\n", 10.43454);
return 0;
}
My output is:
0.5234310000
10.4345400000
Why doesn't this work?

The number before the . is minimum characters total, not just before the radix point.
printf("%21.10f\n", 0.523431);

When you use "%10.10f" you are telling printf() "use 10 character positions to print the number (optional minus sign, integer part, decimal point and decimal part). From these 10 positions, reserve 10 for decimal part. If this is not possible, ignore the first number and use whatever positions needed to print the number so that the number of decimal positions is kept"
So that's what's printf() is doing.
So you need to indicate how many positions you are going to use, for example, 15, and how many positions from these are going to be decimals.... for example, 9. That will leave you with 5 positions for the minus sign and integer part and one position for the decimal point.
That is, try "%15.9f" in your printf's

Related

Why double and %f don't want to print 10 decimals?

I am learning c programming language and am figuring out format specifiers, but it seems as if double and %f are not working corectly.
Here is my code
#include <stdio.h>
int main(void)
{
double a = 15.1234567899876;
printf("%13.10f", a);
}
In my textbook it's stated that in "%13.10f" 13 stands for total number of digits we want to be printed(including dot) and 10 is number of decimals. So i expected to get 15.1234567899 but didn't.
After running it I get 15.1234567900. It's not just not enough decimals, but decimals are not printed correctly. Variable a has 8 after 7 and before 9, but printed number does not.
Can someone please tell me where am I wrong.
Thank you. Lp
printf is supposed to round the result to the number of digits you asked for.
you asked: 15.1234567899876
you got: 15.1234567900
digit count: 1234567890
So printf is behaving correctly.
You should beware, though, that both types float and double have finite precision. Also their finite precision is as a number of binary bits, not decimal digits. So after about 7 digits for a float, and about 16 digits for a double, you'll start seeing results that can seem quite strange if you don't realize what's going on. You can see this if you start printing more digits:
printf("%18.15f\n", a);
you asked: 15.1234567899876
you got: 15.123456789987600
So that's okay. But:
printf("%23.20f\n", a);
you asked: 15.1234567899876
you got: 15.12345678998759979095
Here we see that, at the 15th digit, the number actually stored internally begins to differ slightly from the number you asked for. You can read more about this at Is floating point math broken?
Footnote: What was the number actually stored internally? It was the hexadecimal floating-point number 0xf.1f9add3b7744, or expressed in C's %a format, 0x1.e3f35ba76ee88p+3. Converted back to decimal, it's exactly 15.1234567899875997909475699998438358306884765625. All those other renditions (15.1234567900, 15.123456789987600, and 15.12345678998759979095) are rounded to some smaller number of digits. The internal value makes the most sense, perhaps, expressed in binary, where it's 0b1111.0001111110011010110111010011101101110111010001000, with exactly 53 significant bits, of which 52 are explicit and one implicit, per IEEE-754 double precision.

Algorithm for printing decimal value of a huge(over 128bits) binary number?

TLDR, at the bottom :)
Brief:
I am in a process of creating an basic arithmetic library(addition, subtraction, ...) for handling huge numbers. One of the problem i am facing is printing these huge binary numbers into decimal.
I have huge binary number stored in an array of uint64_t. e.g.
uint64_t a[64] = {0};
Now, the goal is to print the 64*64bits binary number in the console/file as its decimal value.
Initial Work:
To elaborate the problem I want to describe how I printed hex value.
int i;
int s = 1;
a[1] = (uint64_t)0xFF;
for(i = s; i>= 0; i--)
{
printf("0x%08llX, ", a[i]);
}
Output:
0x000000FF, 0x00000000,
Similarly for printing OCT value I can just take LSB 3 bits from a[64], print decimal equivalent of those bits, 3 bits right shift all the bits of a[64] and keep repeating until all the values of a[64] has been printed. (print in revers order to keep first Oct digit on the right)
I can print Hex and Oct value of a binary of unlimited size just by repeating this unit algorithm, but I could not find/develop one for Decimal which I can repeat over and over again to print a[64](or something bigger).
What I have thought of:
My initial idea was to keep subtracting
max_64 =(uint64)10000000000000000000; //(i.e.10^19)
the biggest multiple of 10 inside uint64_t, from a until the value inside a is smaller than max_64 (which is basically equivalent of rem_64 = a%max_64 ) and print the rem_64 value using
printf("%019llu",rem_64);
which is the 1st 19 decimal digits of the number a.
Then do an arithmetic operation similar to (not the code):
a = a/max_64; /* Integer division(no fractional part) to remove right most 19 dec digits from 'a' */
and keep repeating and printing 19 decimal digits. (print in such a way that first found 19 digits are on the right, then next 19 digits on its left and so on...).
The problem is this process is to long and I don't want to use all these to just print the dec value. And was looking for a process which avoids using these huge time consuming arithmetic operations.
What I believe is that there must be a way to print huge size just by repeating an algorithm (similar to how Hex and Oct can be printed) and I hope someone could point me to the right direction.
What my library can do(so far):
Add (Using Full-Adder)
Sub (Using Full-subtractor)
Compare (by comparing array size and comparing array elements)
Div (Integer division, no fractional part)
Modulus (%)
Multiplication (basically adding from several times :( )
I will write code for other operations if needed, but I would like to implement the printing function independent of the library if possible.
Consider the problem like this:
You have been given a binary number X of n bits (1<=n<=64*64) you have to print out X in decimal. You can use existing library if absolutely needed but better if unused.
TLDR:
Any code, reference or unit algorithm which I can repeat for printing decimal value of a binary of too big and/or unknown size would be much helpful. Emphasis on algorithm i.e. I don't need a code if some one could describe a process I will be able to implement it. Thanks in advance.
When faced with such doubts, and given that there are many bigint libraries out there, it is interesting to look into their code. I had a look at Java's BigInteger, which has a toString method, and they do two things:
for small numbers, they bite the bullet and do something similar to what you proposed - straightforward link-by-link base conversion, outputting decimal numbers in each step.
for large numbers, they use the recursive Schönhage algorithm, which they quote in the comments as being referred to in, among other places,
Knuth, Donald, The Art of Computer Programming, Vol. 2, Answers to
Exercises (4.4) Question 14.

Setting the digits after decimal point

So with float when I enter some number it prints with 6 decimal digits. I know I can adjust number of digits with something like "%.2f" (then number has only two). But my question is; is there any command that prints exact number of digits that are inputed.
Example if I input number 2.5
With only printf ("%f", number); it will print 2.500000
Or with printf ("%.2f", number); it will print 2.50
So is there any way that it could print 2.5 (with one decimal point) and in the same time if I input number like 2.51 it will print that number with 2 decimal points (2.51)
Yes. To do so, you would have to write some code to determine how many places after the decimal point you need to print.
I'll leave converting the pseudo-code below to actual code to you:
value = 2.51
places = 1
while(testDigitsAfterDecimal(value, places) { places ++ }
sprintf(format_string, "%%.%df", places)
printf(format_string, value)
In summary, if you write code to mathematically test for places following the decimal and keep count of how many places you need, you can then use that number in a sprintf to create a format string that specifies the desired number of places. With that done, you can pass that string to printf as the format to print your number.

Pretty print a double number in a fixed number of chars

What is the simplest solution to print a double (printf) in C so that:
exactly N characters are used (will be around 6) for all double numbers (nan and infinities are handled separately), positive and negative alike (+ or - always as first char);
decimal representation ('.' always present) is used as long as the numeric chars are not all 0 (i.e. too small number) or the decimal point is the last of the N char (i.e too big number). Otherwise switch to scientific representation, always occupying exactly N chars.
All the solutions I can think of seem quite involved, any idea to obtain this result easily (efficiency is not a concern here) ?
Thanks!
I could not find a way to do this via a single printf call, here is my solution.
At least 9 chars must be used as (with +- in front) that's the minimum amount of chars for scientific notation (for example: +1.0E-002). In the following I consider the case of 9 chars. The following two formats are used based on the conditions reported below:
Scientific format '%+.1e':
chars 4 to 9 as per decimal format are 0 and the number is not identical to 0 (i.e. too small for decimal)
the '.' char is not present between char 3 and char 8 as per decimal format (i.e. too large for decimal)
Decimal format '%+.6f':
Infinite or nan
All other cases
It's easy to adapt to a representation longer than 9 chars by changing the constants above.

Floating point results

In my C code:
I see some of the results in floating point come out to be for example 2.404567E+1. it seems to me that for results less then 1 the results turn out to be in some exponential series.
So, I have 2 questions:
how can I get the result rounded off to some digits ie instead of 5.23542342734 I just want the result to be 5.23
How can I get rid of exponential results and get results as for example 0.1648 instead of 1.6483517E-1
You can control the output format of printf() (I'm assuming you're talking about printf()?) in a number of ways. e.g.:
printf("%.2f\n", 5.23542342734); // Prints "5.23"
printf("%.4f\n", 1.6483517E-1); // Prints "0.1648"
See e.g. http://www.cplusplus.com/reference/clibrary/cstdio/printf/ (or a million other references out there on the internet) for more details on format specifiers for printf().
Adjust format string:
printf ("%.2f", float_data);
http://linux.die.net/man/3/printf
Or to use to truncate/approximate the value to some decimal places, i think the following should work:
trunc = floor (float_val * 10000) / 10000;
The above will preserve only upto 4 decimal places of float_var and store it to trunc. Use round () if needed.

Resources