最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

printf - Can snprintf format '-0'? - Stack Overflow

programmeradmin2浏览0评论

On AVR 8-bit, avoiding floats, I'm dividing a signed integer and formatting it with snprintf:

int16_t tempx10 = -5;
div_t temp = div(tempx10, 10);
char buf[10];
snprintf(buf, sizeof (buf), "%4d.%d°", temp.quot, abs(temp.rem));

This however produces 0.5 instead of -0.5.

What would be an elegant way to solve this?

On AVR 8-bit, avoiding floats, I'm dividing a signed integer and formatting it with snprintf:

int16_t tempx10 = -5;
div_t temp = div(tempx10, 10);
char buf[10];
snprintf(buf, sizeof (buf), "%4d.%d°", temp.quot, abs(temp.rem));

This however produces 0.5 instead of -0.5.

What would be an elegant way to solve this?

Share edited Mar 7 at 15:03 elechris 4753 silver badges16 bronze badges asked Mar 7 at 11:37 Torsten RömerTorsten Römer 3,9584 gold badges45 silver badges57 bronze badges 3
  • 1 soo "%s...", tmpx10 < 0 ? "-" : "+", ....? – KamilCuk Commented Mar 7 at 11:44
  • that produces something like - -1.5° – Torsten Römer Commented Mar 7 at 11:51
  • there's no easy way to justify - with 1 to the right. You have to write code to handle it, yes. – KamilCuk Commented Mar 7 at 12:00
Add a comment  | 

2 Answers 2

Reset to default 4

The code that you provided omitted the negative sign when temp.quot was zero because div() returns a zero quotient for -5/10, and the format string didn't account for the original value's sign. You can add the sign manually and you can use abs(temp.quot) to prevent the quotient from repeating its sign. You can do it this way.

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

int main() {
    int16_t tempx10 = -5;
    div_t temp = div(tempx10, 10);
    char buf[10];

    snprintf(buf, sizeof(buf), "%c%d.%d°",
             (tempx10 < 0) ? '-' : ' ',
             abs(temp.quot),    
             abs(temp.rem));

    printf("Result: %s\n", buf);  
    return 0;
}

Output:

Result: -0.5°

The code you are using is quite costly on AVR (division, sprintf), so here is a solution that only invokes some character operations. The printf is only used to print the result.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void prt (int16_t tempx10)
{
    char buf[10];
    itoa (tempx10, buf, 10);
    size_t len = strlen (buf);

    // Position of the last digit.  Will become digit after '.'.
    char *p = buf + len - 1;
    char decimal = *p;
    if (tempx10 < 10 && tempx10 > -10)
        *p++ = '0';
    *p++ = '.';
    *p++ = decimal;
    *p++ = '\0';

    printf ("Temp = %s\n", buf);
}

int main (void)
{
    for (int i = -15; i <= 15; i+= 5)
        prt (i);
    return 0;
}

Ouput

Temp = -1.5
Temp = -1.0
Temp = -0.5
Temp = 0.0
Temp = 0.5
Temp = 1.0
Temp = 1.5
发布评论

评论列表(0)

  1. 暂无评论