Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Korean
  4. double 소수점 계산 관련 문의
Forum Update on Monday, May 27th 2025

double 소수점 계산 관련 문의

Scheduled Pinned Locked Moved Unsolved Korean
4 Posts 2 Posters 1.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    hlowd
    wrote on last edited by hlowd
    #1

    안녕하세요.

    qt 5.12.x 버전 사용중에 있고 소수점 계산 중에 궁금한 부분이 있어 문의드립니다.

    double a = 0.00025;
    double sum = 0.0;

    for(int i = 0; i < 100000; i++)
    {
    sum += a;
    }

    이렇게 계산을 할 경우 0.00025씩 증가하여야 하는데 값을 출력해보면 0.827998 이런식으로 깨져서 표시됩니다.

    아래와 같이 ceil이나 round 함수를 사용해도 0.00025씩 동일하게 증가하여 표시되게 하는 좋은 방법이 없을까요?

    ceil(a * 1000000) / 1000000;
    round(a * 1000000) / 1000000;

    ps) window 10, ubuntu 20.04 버전 동일합니다.

    Paul ColbyP 1 Reply Last reply
    0
    • H hlowd

      안녕하세요.

      qt 5.12.x 버전 사용중에 있고 소수점 계산 중에 궁금한 부분이 있어 문의드립니다.

      double a = 0.00025;
      double sum = 0.0;

      for(int i = 0; i < 100000; i++)
      {
      sum += a;
      }

      이렇게 계산을 할 경우 0.00025씩 증가하여야 하는데 값을 출력해보면 0.827998 이런식으로 깨져서 표시됩니다.

      아래와 같이 ceil이나 round 함수를 사용해도 0.00025씩 동일하게 증가하여 표시되게 하는 좋은 방법이 없을까요?

      ceil(a * 1000000) / 1000000;
      round(a * 1000000) / 1000000;

      ps) window 10, ubuntu 20.04 버전 동일합니다.

      Paul ColbyP Offline
      Paul ColbyP Offline
      Paul Colby
      wrote on last edited by
      #2

      Hi @hlowd, what you are seeing here an accumulative floating point error that comes from the fact that floating point numbers cannot represent every possible number exactly.

      The solution is to use a fixed-point approach instead of floating - ie using integers, but where the integers represent a decimal fraction instead of whole units.

      Easier explained with an example:

      This doesn't work, as you've shown already:

      #include <iostream>
      
      int main() {
        double a = 0.00025;
        double sum = 0.0;
        for(int i = 0; i < 100000; i++) {
          sum += a;
          std::cout << sum << std::endl;
        }
      }
      

      Outputs:

      0.00025
      0.0005
      0.00075
      0.001
      0.00125
      ...
      24.999
      24.9993
      24.9995
      24.9998
      25
      

      But this version:

      #include <iomanip>
      #include <iostream>
      
      int main() {   
        uint64_t a = 25; 
        uint64_t sum = 0;
        for(int i = 0; i < 100000; i++) {
          sum += a;
          std::cout << (sum/100000) << '.' << std::setfill('0') << std::setw(5) << (sum%10000) << std::endl;
        }
      }
      

      Outputs what you want (if I understand you correctly):

      0.00025
      0.00050
      0.00075
      0.00100
      0.00125
      ...
      24.09900
      24.09925
      24.09950
      24.09975
      25.00000
      

      Of course, the std::* stuff can be replaced with Qt-specific equivalents, but the problem is not specific to Qt (indeed, not specific to C++ either, but modern FPUs).

      Cheers.

      H 1 Reply Last reply
      0
      • Paul ColbyP Paul Colby

        Hi @hlowd, what you are seeing here an accumulative floating point error that comes from the fact that floating point numbers cannot represent every possible number exactly.

        The solution is to use a fixed-point approach instead of floating - ie using integers, but where the integers represent a decimal fraction instead of whole units.

        Easier explained with an example:

        This doesn't work, as you've shown already:

        #include <iostream>
        
        int main() {
          double a = 0.00025;
          double sum = 0.0;
          for(int i = 0; i < 100000; i++) {
            sum += a;
            std::cout << sum << std::endl;
          }
        }
        

        Outputs:

        0.00025
        0.0005
        0.00075
        0.001
        0.00125
        ...
        24.999
        24.9993
        24.9995
        24.9998
        25
        

        But this version:

        #include <iomanip>
        #include <iostream>
        
        int main() {   
          uint64_t a = 25; 
          uint64_t sum = 0;
          for(int i = 0; i < 100000; i++) {
            sum += a;
            std::cout << (sum/100000) << '.' << std::setfill('0') << std::setw(5) << (sum%10000) << std::endl;
          }
        }
        

        Outputs what you want (if I understand you correctly):

        0.00025
        0.00050
        0.00075
        0.00100
        0.00125
        ...
        24.09900
        24.09925
        24.09950
        24.09975
        25.00000
        

        Of course, the std::* stuff can be replaced with Qt-specific equivalents, but the problem is not specific to Qt (indeed, not specific to C++ either, but modern FPUs).

        Cheers.

        H Offline
        H Offline
        hlowd
        wrote on last edited by
        #3

        @Paul-Colby
        안녕하세요.

        우선 바쁘신 와중에 답변주셔서 감사합니다.

        답변해주신 부분에 대해 추가적으로 궁금한 내용이 있습니다.

        더해지는 값을 double 형 변수에 저장하는 것은 어려울까요?

        Paul ColbyP 1 Reply Last reply
        0
        • H hlowd

          @Paul-Colby
          안녕하세요.

          우선 바쁘신 와중에 답변주셔서 감사합니다.

          답변해주신 부분에 대해 추가적으로 궁금한 내용이 있습니다.

          더해지는 값을 double 형 변수에 저장하는 것은 어려울까요?

          Paul ColbyP Offline
          Paul ColbyP Offline
          Paul Colby
          wrote on last edited by
          #4

          @hlowd said in double 소수점 계산 관련 문의:

          더해지는 값을 double 형 변수에 저장하는 것은 어려울까요?

          Sure, you can convert the results to floating point numbers at any stage - eg inside the loop, or a the very end. For example:

          #include <iomanip>
          #include <iostream>
          
          int main() {   
            uint64_t a = 25; 
            uint64_t sum = 0;
            for(int i = 0; i < 100000; i++) {
              sum += a;
              const double sumAsFloat = sum/100000.0;
              std::cout << (sum/100000) << '.' << std::setfill('0') << std::setw(5) << (sum%100000)
                        << std::setprecision(10) << "  \t[" << sumAsFloat << ']' << std::endl;
            }
          }
          

          Outputs:

          0.00025         [0.00025]
          0.00050         [0.0005]
          0.00075         [0.00075]
          0.00100         [0.001]
          0.00125         [0.00125]
          24.99900        [24.999]
          24.99925        [24.99925]
          24.99950        [24.9995]
          24.99975        [24.99975]
          25.00000        [25]
          

          Cheers.

          PS: In printing both the uint64_t and double versions side-by-side, I realised there's was a small error in my previous reply, where the (sum%10000) should have had another 0, ie (sum%100000). I fixed that in the code in this reply :)

          1 Reply Last reply
          1

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved