소수점 표시

kkb의 이미지

int value = 42195;
 
printf("value = %d.%03d \n", value/1000, abs(value%1000));

value가 42195 일때,
value = 42.195와 같이 찍으려고 하는데
이와 같은 코드가 엄청 많아서

#define INT(val) (val/1000)
#define DEC(val) abs(val%1000)
 
int value;
 
printf("value = %d.%03d \n", INT(value), DEC(value));

이렇게 한번 바꾸어 보았습니다.

더 간단하고 보기 좋게 할 수 있는 방법이 있을까요?

혹시, 아래와 같이 하는 것은 안좋죠?

#define INT(val) (val/1000)
#define DEC(val) abs(val%1000)
#define COMB(val) INT(val),DEC(val)
 
int value;
 
printf("value = %d.%03d \n", COMB(value));
라스코니의 이미지

소수점을 찍는 rule이 뭔지는 모르겠지만 저라면

char buf[100];
sprintf(buf, "%d", value);
printf("%c%c.%s\n", buf[0], buf[1], &buf[2]);

로 일단 해볼 거 같네요. 테스트는 안해봤습니다.

kkb의 이미지

답변 감사합니다

질문글에서도 이미 말씀 드렸지만
말씀하신대로 하면 코드가 아래와 같이 되어서
그걸 최대한 간단하고 보기 좋게 패턴화하려는 것이 질문입니다.
어떤 식으로 찍을 것이냐의 질문은 아니고요.
실제 출력은 아래보다 훨씬 많습니다.

그리고 말씀하신 코드는 102506이라는 값 즉, 102.506이나 3141 즉, 3.141에 대해서 유연성이 떨어질 것 같네요.

char buf[100];
sprintf(buf, "%d", value1);
printf("%c%c.%s\n", buf[0], buf[1], &buf[2]);
sprintf(buf, "%d", value2);
printf("%c%c.%s, %c%c.%s, %c%c.%s\n", buf[0], buf[1], &buf[2], buf[0], buf[1], &buf[2], buf[0], buf[1], &buf[2]);
sprintf(buf, "%d", value3);
printf("%c%c.%s\n", buf[0], buf[1], &buf[2]);
sprintf(buf, "%d", value4);
printf("%c%c.%s\n", buf[0], buf[1], &buf[2]);
sprintf(buf, "%d", value5);
printf("%c%c.%s\n", buf[0], buf[1], &buf[2]);
printf("%c%c.%s, %c%c.%s, %c%c.%s\n", buf[0], buf[1], &buf[2], buf[0], buf[1], &buf[2], buf[0], buf[1], &buf[2]);
sprintf(buf, "%d", value6);
printf("%c%c.%s, %c%c.%s, %c%c.%s\n", buf[0], buf[1], &buf[2], buf[0], buf[1], &buf[2], buf[0], buf[1], &buf[2]);
sprintf(buf, "%d", value7);
printf("%c%c.%s, %c%c.%s\n", buf[0], buf[1], &buf[2], buf[0], buf[1], &buf[2]);
sprintf(buf, "%d", value8);
printf("%c%c.%s\n", buf[0], buf[1], &buf[2]);
sprintf(buf, "%d", value9);
printf("%c%c.%s\n", buf[0], buf[1], &buf[2]);
sprintf(buf, "%d", value10);
printf("%c%c.%s\n", buf[0], buf[1], &buf[2]);
sprintf(buf, "%d", value11);
printf("%c%c.%s\n", buf[0], buf[1], &buf[2]);
sprintf(buf, "%d", value12);
printf("%c%c.%s, %c%c.%s\n", buf[0], buf[1], &buf[2], buf[0], buf[1], &buf[2]);
sprintf(buf, "%d", value13);
printf("%c%c.%s\n", buf[0], buf[1], &buf[2]);
 
sprintf(buf, "%d", value99);
printf("%c%c.%s, %c%c.%s, %c%c.%s\n", buf[0], buf[1], &buf[2], buf[0], buf[1], &buf[2], buf[0], buf[1], &buf[2]);
sprintf(buf, "%d", value100);
printf("%c%c.%s\n", buf[0], buf[1], &buf[2]);
sprintf(buf, "%d", value);

라스코니의 이미지

#include <stdio.h>
#include <string.h>
 
#define show_something(buf, value) \
    do { \
       sprintf(buf, "%d", value); \
       int len = strlen(buf); \
       int indx = 0; \
       while(indx < len-3) \
           putchar(buf[indx++]); \
       printf(".%s\n", &buf[indx]); \
    } while(0)
 
 
int main()
{
    int i = 12345678;
    int j = 3141592;
    char buf[100];
 
    printf("Hello World\n");
 
    show_something(buf, i);
    show_something(buf, j);
 
    return 0;
}

이런 걸 원하시나요?
kkb의 이미지

답변 감사합니다.

그것도 좋지만
그렇게 할거면 아래와 같이 하는 것이 훨씬 간단하지 않을까요?
이런 걸 원한 건 아닌데
커널코드에서의 소수출력 부분(소수 정의가 안되니까)도 찾아봤는데
딱히 간단하게 한 건 없더라구요.
간단히 되는 게 아닌가보네요.
감사합니다.

#define show_something(buf, value) \
    do { \
       sprintf(buf, "%d.%03d", value/1000, abs(value%1000)); \
    } while(0)

라스코니의 이미지

아마 정수를 1/1000 한 값을 나타내는 것으로 보이는데 음수와 1000보다 작은 값은 좀 까다롭네요.
아래와 같이 수정해 봤습니다. 개인적으로 /, % 연산자는 가급적 안쓰는 관계로 복잡한 것은 참고만 하세요.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
#define show_something(buf, value) \
    do { \
        sprintf(buf, "%d", value); \
        int len = strlen(buf); \
        int indx = 0; \
        int shortFlag = (buf[0] == '-') ? ((len < 5) ? 1 : 0) : ((len < 4) ? 1 : 0); \
        if(shortFlag) { \
            if(buf[indx] == '-') \
                putchar(buf[indx++]); \
            putchar('0'); \
            putchar('.'); \
            int indx_temp = 3-(len-indx); \
            while(indx_temp--) { \
                putchar('0'); \
            } \
            while(indx < len) \
                putchar(buf[indx++]); \
            printf("\n"); \
        } \
        else { \
            while(indx < len-3) \
                putchar(buf[indx++]); \
            printf(".%s\n", &buf[indx]); \
        } \
    } while(0)
 
#define show_something1(buf, value) \
    do { \
       int temp = value; \
       int offset = (temp < 0) ? 1 : 0; \
       sprintf(buf, "%s", (offset > 0) ? "-" : ""); \
       temp = abs(temp); \
       sprintf(&buf[offset], "%d.%03d", temp/1000, temp%1000); \
       printf("%s\n", buf); \
    } while(0)
 
int main()
{
    int i = 12345678;
    int j = 3141592;
    int k = -2;
    int l = -1234556;
    int m = -342;
    int n = 45;
    char buf[100];
 
    printf("Hello World\n");
 
    show_something(buf, i);
    show_something(buf, j);
    show_something(buf, k);
    show_something(buf, l);
    show_something(buf, m);
    show_something(buf, n);
 
    printf("\n\n");
 
    show_something1(buf, i);
    show_something1(buf, j);
    show_something1(buf, k);
    show_something1(buf, l);
    show_something1(buf, m);
    show_something1(buf, n);
 
    return 0;
}

Hello World
12345.678
3141.592
-0.002
-1234.556
-0.342
0.045

12345.678
3141.592
-0.002
-1234.556
-0.342
0.045

라스코니의 이미지

이게 더 낫겠네요.

#define show_something1(buf, value) \
    do { \
       int temp = value; \
       temp = abs(temp); \
       sprintf(buf, "%s%d.%03d", (value < 0) ? "-" : "", temp/1000, temp%1000); \
       printf("%s\n", buf); \
    } while(0)

익명 사용자의 이미지

value가 음수일 때 테스트 해보세요. 원하시는 결과인지.

익명 사용자의 이미지

아, abs가 있군요. :)

익명 사용자의 이미지

지금까지 올라온 코드 중 두 개를 조금 변형해서...

#define INT(val) ((val)/1000)
#define DEC(val) abs((val)%1000)
 
int value;
 
printf("value = %d.%03d \n", INT(value), DEC(value));

또는

#define show_something(buf, value) \
    do { \
        int tmp = (value); \
        sprintf(buf, "%d.%03d", tmp/1000, abs(tmp%1000)); \
    } while(0)

를 선호합니다.

======

#define INT(val) (val/1000)
#define DEC(val) abs(val%1000)
#define COMB(val) INT(val),DEC(val)
 
int value;
 
printf("value = %d.%03d \n", COMB(++value)); // ??!
 
#define show_something(buf, value) \
    do { \
        sprintf(buf, "%d.%03d", value/1000, abs(value%1000)); \
    } while(0)
 
show_something(++value); // ??!

괜한 걱정처럼 들릴 수 있는 점 알고 있습니다만, 매개변수를 두 번 이상 평가하는 C/C++ 매크로는 별로 좋아하지 않습니다.

매개변수에 함수 호출 표현식이라던가 기타 side effect가 있는 수식을 넣어서는 안 된다는 걸, 매크로를 작성한 사람은 알더라도 다른 사람은 모를 수 있으니까요.

kkb의 이미지

맞는 말씀입니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.