0

I'm programming a microcontroller in C and since the compiler or chip doesn't handle Floating Point numbers very well, it is recommended to scale the floating point value up enough to get rid of the decimal and then when outputting the number, scale it back down with a proportional division and use modulus to find and display the fractional part. Here's an example: Start with number 25.0625. Multiply by 10000 to get 250625. Good now we don't have a float anymore. Now to display this we use a line like this:

sprintf(buffer, "%li.%i", Temp / 10000, abs(Temp % 10000));

So we first get the 25 back out by / 10000, then we get the 0625 out by % 10000. Here's the problem though: It appears my modulus result ignores the leading zero in 0625 so when it concatenates the number back together, it becomes 25.625 instead of 25.0625. I can't count on there always being a leading zero, so stuffing a zero in there isn't the answer, and there could at other times be several leading zeros. My question is, how do I suppress the modulus from excluding leading zeros ? Thanks.

Barmar
  • 741,623
  • 53
  • 500
  • 612

1 Answers1

3

You can tell sprintf to format the number in a 4-digit field with leading zeroes.

sprintf(buffer, "%li.%04d", Temp / 10000, abs(Temp % 10000));

See Printing leading 0's in C?

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Also `%.4d` does the same job. There are some who argue it is preferred over `%04d`. – Jonathan Leffler Oct 03 '17 at 06:40
  • @JonathanLeffler I don't see that recommendation in any of the answers to the question I just linked to. – Barmar Oct 03 '17 at 06:46
  • It does seem to be missing. I’d want to dig up a reference for “there are those who…” before going much further. The x-red is also about zip codes rather than integer/fixed-point arithmetic. – Jonathan Leffler Oct 03 '17 at 06:53
  • @JonathanLeffler [here](https://stackoverflow.com/questions/44394291/precision-field-in-printf-when-formatting-integer) is a question that discusses the difference, which only affects negative numbers. In my experience, `%04d` is more idiomatic. – Barmar Oct 03 '17 at 06:58
  • I went digging. The [C99 Rationale](http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf) documents this (p152): _The use of leading zero in field widths to specify zero padding is superseded by a precision field. The older mechanism was retained._ The commentary applied to the C90 standard too (it wasn't added for C99). I'd not dispute that you see `%04d` at least as often as `%.4d` in many circles. It was intended to be an informative comment rather than serious criticism. – Jonathan Leffler Oct 03 '17 at 07:00
  • @JonathanLeffler I also find the `0` modifier to be more mnemonic, and it's consistent with formatting floating point (for which the precision specifies digits after the decimal). – Barmar Oct 03 '17 at 07:11
  • Note that this outputs `"0.1234"` for `Temp = -1234;` where certainly `"-0.1234"` is desired. – chux - Reinstate Monica Oct 03 '17 at 12:58
  • 1
    @chux Good point, because integers don't have negative zero for `-1234/10000`. The code needs to check for this case. – Barmar Oct 03 '17 at 15:15