0

My question is very simple. I don't know how I could count the charactere in double ? For example : 13.43, answer is 4.

I may use (% 10) but I'am not able to find a right method with digital number.

int i = 0;
double a = 13.43;

while (a != 0)
{
    a = a / 10;
    i++;
}

Thanks to this data, I will create a malloc with a right dimension.

Thanks.

Fuzion
  • 11
  • 1
  • 2
    the loop may be longer than you think ... use sprintf... – Jean-François Fabre Nov 11 '16 at 17:34
  • 1
    Declare a large enough string: `char str[100]`. Copy the value into it: `sprintf(str,"%lf",a);`. Call `i = strlen(str)`. – barak manos Nov 11 '16 at 17:35
  • 3
    What are you _actually_ trying to achieve ? This sounds like an [XY Problem](http://xyproblem.info/) to me. – Jabberwocky Nov 11 '16 at 17:36
  • Yes, but I don't like to declare a large string. I must optimize my code. – Fuzion Nov 11 '16 at 17:37
  • the problem is float representation. Your float is actually a _decimal_. – Jean-François Fabre Nov 11 '16 at 17:40
  • @Fuzion why do you need to know the length ? Give us a broader picture of your problem. Read my previous comment (including the link to [XY Problem](http://xyproblem.info/). _I must optimize my code_: optimize in what way ? How many of those doubles do you need to store. – Jabberwocky Nov 11 '16 at 17:42
  • A double doesn't have characters. It depends on the usage details how many digits are significant/valid. You have to provide that. – Avi Berger Nov 11 '16 at 17:42
  • 1
    @barakmanos: Much better to use the return value of snprintf()... – psmears Nov 11 '16 at 17:45
  • @psmears: That's in order to make sure that the value has been copied (otherwise `str` will not be null-terminated, and the following call to `strlen` will lead to UB). But it's a little difficult to give all this in a comment... – barak manos Nov 11 '16 at 17:48
  • @barakmanos: (1) No need to worry about null terminating - snprintf() will *always* null-terminate. (2) You don't even need to make the buffer big enough - snprintf() will always return the number of characters, even if the buffer was too small! – psmears Nov 11 '16 at 17:49
  • @psmears: I doubt that it will do so upon failure (though, I can't see how it ould fail, but if it somehow returns 0, then I guess that it does). – barak manos Nov 11 '16 at 17:50
  • Very similar questions asked all over, e.g., [here](http://stackoverflow.com/questions/5459437/given-a-double-need-to-find-how-many-digits-in-total), [here](http://stackoverflow.com/questions/31690417/count-the-number-of-digits-of-a-floating-point-number), and [here](http://stackoverflow.com/questions/29023641/counting-number-of-digits-in-a-double-c). – Joel Nov 11 '16 at 17:52
  • @barakmanos: in the unlikely event that sprintf/snprintf fail, then your suggested code is equally broken :) – psmears Nov 11 '16 at 17:53
  • I just tested `counter = snprintf ( s, 1, "%lf", a );` and got `counter = -1`. After increasing the length to 100, I got `counter = 9`. So it seems that it doesn't return the number when buffer is too small. – Jean-François Fabre Nov 11 '16 at 17:53
  • @psmears: In fact, you don't even need a buffer if the buffer length is 0: `int len = snprintf(NULL, 0, "%g", 13.43);` – Ian Abbott Nov 11 '16 at 18:15
  • @jeanfrançoisfabre: your implementation is not C99 (windows?) – pmg Nov 11 '16 at 18:16
  • @IanAbbott - yes, I know, but I didn't want to confuse the issue even further than I already seem to have done ;-) – psmears Nov 11 '16 at 18:18

4 Answers4

3

Thanks to this data, I will create a malloc with a right dimension.

Don't worry about it. Just allocate 32 bytes.

A double can always be represented in 24 characters or less using scientific notation.

Allocating a couple of bytes more than you need will not increase your application's memory usage. Most malloc() implementations round allocations up to the next 8 bytes (sometimes even 16 or 32) for alignment purposes, so allocating an "odd" number like 24 bytes will result in the same memory usage as if you'd allocated 32.

Community
  • 1
  • 1
2

Use snprintf() for C99 or more recent (use a large enough buffer for C89).

n = snprintf(NULL, 0, "%.2f", a);
data = malloc(n + 1);

http://pubs.opengroup.org/onlinepubs/9699919799/functions/snprintf.html

pmg
  • 106,608
  • 13
  • 126
  • 198
1

You should know, if you have a finite decimal you may not have a finite binary.

For instance 0.1 in Decimal:

0.1 * 2 = 0.2 -> 0
0.2 * 2 = 0.4 -> 0
0.4 * 2 = 0.8 -> 0
0.8 * 2 = 1.6 -> 1
0.6 * 2 = 1.2 -> 1
0.1 * 2 = 0.2 -> 0
0.2 * 2 = 0.4 -> 0
0.4 * 2 = 0.8 -> 0
0.8 * 2 = 1.6 -> 1
0.6 * 2 = 1.2 -> 1
0.1 * 2 = 0.2 -> 0
0.2 * 2 = 0.4 -> 0
0.4 * 2 = 0.8 -> 0
0.8 * 2 = 1.6 -> 1
0.6 * 2 = 1.2 -> 1 (and repeat infinitely)

So, 0.1 in Decimal is 0.000110001100011...

So maybe it's your problem and you should learn about the mantissa.

This is why some languages record their floating point numbers as fractions.

psmears
  • 26,070
  • 4
  • 40
  • 48
Aodren BARY
  • 121
  • 9
  • The converse is not true, though. Every binary fraction (like a `double`) can be represented as a finite decimal. –  Nov 11 '16 at 17:57
  • Also, while some languages may use fractions to represent real numbers (I've never seen one, though), those are, by definition, not _floating-point numbers_. –  Nov 11 '16 at 17:57
-1

Maybe you can try this, I didnt test the code so I am not 100% sure it will work, but it should. I am also sure it can be optimized. Give it a try and let us know!

while ( number/10 > 10 )
{
    number = number/10;     // Analyzing integer part
    quantity++;
}
number = number/10;

if (number == 10)
{
    quantity = quantity + 2;
}
else
{
    quantity++;
}

quantity++; // One more character for .

remaining = number % 1;

while (remaining/10 > 10)
{
    quantity++;             // Analyzing decimal part
    remaining=remaining/10;
}
remaining = remaining/10;

if (remaining = 10)
{
    quantity = quantity + 2;
}
else
{
    quantity++;
}
cventu
  • 255
  • 1
  • 5
  • 13