Thread: How to find how many places from left the dot appears in a flot/double?

  1. #1
    Registered User
    Join Date
    Oct 2021
    Posts
    138

    How to find how many places from left the dot appears in a flot/double?

    Let's say that I have the following float/double: 137.837

    How can I find how many places from left the dot appears? So in this example I want to take either three or four (depending on how you think it). Does anyone knows how I can do that and can explain it to me?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Oct 2021
    Posts
    138
    Quote Originally Posted by Salem View Post
    Thanks! It seems to work. I did something like the following:

    ```
    float val = 1384.838;
    int digits_before_dot = (unsigned int)log10(val);
    ```

    It will return 3 so I always have to add (1) to the result to get the actual number of digits from the left.
    Thanks a lot and happy new year!

  4. #4
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    What happens if val is negative?

  5. #5
    Registered User
    Join Date
    Oct 2021
    Posts
    138
    Quote Originally Posted by flp1969 View Post
    What happens if val is negative?
    If the value is negative or less that 1.0 (so for example: 0.388), it will not work. So you do something like that:

    Code:
      bool negated = false; // To be used later to know if the value was negative
    if (n < 0.0) { // Suppose "n" is your floating number     
       n = -n;
       negated = true;
    }
    
    // Get the fraction digit amount
    unsigned short afterpoint;
    if (n < 1.0) { afterpoint = 2; }
    
    else {     afterpoint = log10(n) + 2;   }
    After that you stop at the dot. So for the number "1384.838", it will give you 5.
    Also note that I haven't compiled the code, there may be typos.

  6. #6
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Just a thought:

    Code:
    unsigned int intdigits( double x ) { x = log10(fabs(x)); if ( x < 0.0 ) return 1; else return ceil(x); }

  7. #7
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    @flp, It should be:
    Code:
    int intdigits(double x)
    {
        x = log10(fabs(x));
        return x < 0 ? 1 : floor(x) + 1;
    }
    Testing:
    Code:
    #include <stdio.h>
    #include <math.h>
     
    int intdigits(double x)
    {
        x = log10(fabs(x));
        return x < 0 ? 1 : ceil(x);
    }
     
    int intdigits2(double x)
    {
        x = log10(fabs(x));
        return x < 0 ? 1 : floor(x) + 1;
    }
     
    int main()
    {
        for (double x = -11; x <= 11; ++x)
            printf("%5.1f: %2d %2d\n", x, intdigits(x), intdigits2(x));
        return 0;
    }
    
    Results:
    -11.0:  2  2
    -10.0:  1  2
     -9.0:  1  1
     -8.0:  1  1
     -7.0:  1  1
     -6.0:  1  1
     -5.0:  1  1
     -4.0:  1  1
     -3.0:  1  1
     -2.0:  1  1
     -1.0:  0  1
      0.0:  1  1
      1.0:  0  1
      2.0:  1  1
      3.0:  1  1
      4.0:  1  1
      5.0:  1  1
      6.0:  1  1
      7.0:  1  1
      8.0:  1  1
      9.0:  1  1
     10.0:  1  2
     11.0:  2  2
    A little inaccuracy saves tons of explanation. - H.H. Munro

  8. #8
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    john, you are absolutely right! I thought about using floor later...

    []s
    Fred

  9. #9
    Registered User
    Join Date
    Oct 2021
    Posts
    138
    Yeah but why call another function and make it run slower? Isn't my example working?

  10. #10
    Registered User
    Join Date
    Sep 2020
    Posts
    150
    Quote Originally Posted by rempas View Post
    Yeah but why call another function and make it run slower? Isn't my example working?
    Why don't you test it with the values from john.c's example and see if you get the same results?

  11. #11
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Quote Originally Posted by rempas View Post
    Yeah but why call another function and make it run slower? Isn't my example working?
    If you are refering to fabs() it's not a function call, since the only thing this function does is to zero the msb. floor() can be avoided, since we are only truncating a positive value:
    Code:
    #include <math.h>
      
    unsigned int intdigits(double x)
    {
      x = log10(fabs(x));
      return x >= 0 ? x + 1 : 1;
    }
    In x86-64 code this will be transtaled to:
    Code:
      bits  64
      default rel
    
      section .text
    
      extern log10
    
      global intdigits
    
      align 16
    intdigits:
      sub         rsp,8
      vandpd      xmm0,xmm0,[.LC0]
      call        log10
      vcomisd     xmm0,[.LC1]
      jb          .L6
      vaddsd      xmm0,xmm0,[.LC2]
      add         rsp,8
      vcvttsd2si  rax,xmm0
      ret
    
      align 4
    .L6:
      mov         eax,1
      add         rsp,8
      ret
    
      section    .rodata
    
      align 16
    .LC0:
      dq  ~(1 << 63)
      dq  0
    
      align 8
    .LC1:
      dq  0.0
    .LC2:
      dq  1.0
    Notice: Only one branch and if log10(fabs(x)) < 0.
    Last edited by flp1969; 12-31-2021 at 07:43 AM.

  12. #12
    Registered User
    Join Date
    Oct 2021
    Posts
    138
    Quote Originally Posted by flp1969 View Post
    If you are refering to fabs() it's not a function call, since the only thing this function does is to zero the msb. floor() can be avoided, since we are only truncating a positive value:
    Code:
    #include <math.h>
      
    unsigned int intdigits(double x)
    {
      x = log10(fabs(x));
      return x >= 0 ? x + 1 : 1;
    }
    In x86-64 code this will be transtaled to:
    Code:
      bits  64
      default rel
    
      section .text
    
      extern log10
    
      global intdigits
    
      align 16
    intdigits:
      sub         rsp,8
      vandpd      xmm0,xmm0,[.LC0]
      call        log10
      vcomisd     xmm0,[.LC1]
      jb          .L6
      vaddsd      xmm0,xmm0,[.LC2]
      add         rsp,8
      vcvttsd2si  rax,xmm0
      ret
    
      align 4
    .L6:
      mov         eax,1
      add         rsp,8
      ret
    
      section    .rodata
    
      align 16
    .LC0:
      dq  ~(1 << 63)
      dq  0
    
      align 8
    .LC1:
      dq  0.0
    .LC2:
      dq  1.0
    Notice: Only one branch and if log10(fabs(x)) < 0.
    That's great however, just like I said, 0.n will not work. The value needs to be at least 1.0

  13. #13
    Registered User
    Join Date
    Sep 2020
    Posts
    150
    Just check if value > 0 and < 1 and return 1

  14. #14
    Registered User
    Join Date
    Oct 2021
    Posts
    138
    Quote Originally Posted by thmm View Post
    Just check if value > 0 and < 1 and return 1
    I did in my original code.

  15. #15
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Quote Originally Posted by rempas View Post
    That's great however, just like I said, 0.n will not work. The value needs to be at least 1.0
    0 isn't a number?

    Let's say we have 0.382:
    Code:
    x = log10(fabs(0.382));  // x = -0.417937
    return x >= 0 ? x + 1 : 1;  // 1
    There is 1 integral algarism there: 0.

    If you need to consider zero (the integral part) as "no algarism", change the final 1 to zero:
    Code:
      return x >= 0 ? x + 1 : 0;
    Last edited by flp1969; 12-31-2021 at 05:29 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 11-24-2012, 12:31 AM
  2. C compiler reads from right to left or left to right?
    By ajishgopalr in forum C Programming
    Replies: 12
    Last Post: 07-16-2011, 08:12 PM
  3. left align, 12 places
    By manav in forum C++ Programming
    Replies: 3
    Last Post: 04-15-2008, 10:39 PM
  4. Replies: 3
    Last Post: 04-05-2008, 07:44 AM
  5. can't use double/float left of %?
    By Shadow12345 in forum C++ Programming
    Replies: 9
    Last Post: 07-31-2002, 11:26 PM

Tags for this Thread