zorrooo February 2016

%c specifier char limit capped in C, how to avoid that?

I am running into a problem when I'm trying to output the fractional part of a hexadecimal number.

Basically, with the following code:

float d2h(float decimal, float fraction) {
  int i = 0;
  char hex[17] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                   'A', 'B', 'C', 'D', 'E', 'F', '\0' };
  int temp = (int) decimal;
  int j;
  for (j = 0; j < 60; j++) {
    fraction = fraction - (int) fraction;
    displayFractionHex[j] = hex[(int) (fraction * 16)];
    fraction *= 16;
  }
  for (i = sizeof(displayDecimalHex) - 1; i >= 0; i--) {
    displayDecimalHex[i] = hex[temp % 16];
    temp /= 16;
  }
  int n;
  if ((n = strspn(displayDecimalHex, "0")) != 0
      && displayDecimalHex[n] != '\0')        // strspn() - Reference
    printf("%s", &displayDecimalHex[n]);
  printf(".");
  for (i = 0; i < 20; i++) {
    printf("%c", displayFractionHex[i]);
  }
}

I get the output 222.74BC0000000000000000, and I obviously want the fractional part of the hex number to display more characters.

However, when I try change the last printf statement to a %s specifier instead of %c, my program crashes.

I have attempted copying the array to another one, unfortunately to no avail.

Answers


chux February 2016

OP commented:

expected output is something along the lines of 222.74bc6a7ef9d...

Typical float has about 24 binary digits of precision as does 222.74BC000000...".

For higher precision use, double.

Use printf("%a\n%a\n", (float) 546.456, 546.456); for example to see the difference.

0x1.113a5ep+9
0x1.113a5e353f7cfp+9

To be clear, "thus the decimal float is 546 and the fractional float is 0.456" is incorrect. The input to d2h(float decimal) was not 546.456, but the closest representable float to it exactly 546.4559936523437500... and that float is exactly 222.74BC in hex FP.

Post Status

Asked in February 2016
Viewed 1,485 times
Voted 6
Answered 1 times

Search




Leave an answer