Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Algorithm Request

Algorithm Request

Scheduled Pinned Locked Moved C / C++ / MFC
algorithmsworkspace
18 Posts 13 Posters 0 Views 1 Watching
  • 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.
  • B Offline
    B Offline
    Barry Etter
    wrote on last edited by
    #1

    I need to take a float or double value nand determine how many numbers it has before and after the decimal. Examples: 123.3 -> 3 before and 1 after .12345 -> 0 before and 5 after 123 -> 3 before and 0 after The method has to be extremely fast because it may be executed very often in a high-volume environment. I know I can convert it to a string and search for the decimal, etc., but string functions are very slow. Thanks! Barry Etter

    _ K C V K 8 Replies Last reply
    0
    • B Barry Etter

      I need to take a float or double value nand determine how many numbers it has before and after the decimal. Examples: 123.3 -> 3 before and 1 after .12345 -> 0 before and 5 after 123 -> 3 before and 0 after The method has to be extremely fast because it may be executed very often in a high-volume environment. I know I can convert it to a string and search for the decimal, etc., but string functions are very slow. Thanks! Barry Etter

      _ Offline
      _ Offline
      _AnsHUMAN_
      wrote on last edited by
      #2

      use CString's Format function CString strFloat; strFloat.Format("%f",myfloatvalue); //Search for . strFloat.Find(); and then use CString's Left() and Right() methods This code is not optimized. It's just one way of doing this Somethings seem HARD to do, until we know how to do them. ;-) _AnShUmAn_

      S J 2 Replies Last reply
      0
      • _ _AnsHUMAN_

        use CString's Format function CString strFloat; strFloat.Format("%f",myfloatvalue); //Search for . strFloat.Find(); and then use CString's Left() and Right() methods This code is not optimized. It's just one way of doing this Somethings seem HARD to do, until we know how to do them. ;-) _AnShUmAn_

        S Offline
        S Offline
        Sarath C
        wrote on last edited by
        #3

        but he is looking for some fast methods I think :) SaRath.
        "It is your attitude, not your aptitude, that determines your altitude - Zig Ziglar." My Blog | Understanding State Pattern in C++

        _ 1 Reply Last reply
        0
        • S Sarath C

          but he is looking for some fast methods I think :) SaRath.
          "It is your attitude, not your aptitude, that determines your altitude - Zig Ziglar." My Blog | Understanding State Pattern in C++

          _ Offline
          _ Offline
          _AnsHUMAN_
          wrote on last edited by
          #4

          Yeap buddy, I read that , That's why I quoted that the method I propose is not optimized and there could be many other methods of achieving the same. Somethings seem HARD to do, until we know how to do them. ;-) _AnShUmAn_

          S 1 Reply Last reply
          0
          • B Barry Etter

            I need to take a float or double value nand determine how many numbers it has before and after the decimal. Examples: 123.3 -> 3 before and 1 after .12345 -> 0 before and 5 after 123 -> 3 before and 0 after The method has to be extremely fast because it may be executed very often in a high-volume environment. I know I can convert it to a string and search for the decimal, etc., but string functions are very slow. Thanks! Barry Etter

            K Offline
            K Offline
            krmed
            wrote on last edited by
            #5

            For the number of digits before the decimal, you could use int iNumBefore = 0; iNumBefore = 1 + (int)(log10(x)); where x is your value As for the number of digits after, I don't have any quick ideas on that, but as you say, you could convert to a string (although you might get different results because of the precision of doubles) and then find the decimal. Hope that helps. Karl - WK5M PP-ASEL-IA (N43CS) PGP Key: 0xDB02E193 PGP Key Fingerprint: 8F06 5A2E 2735 892B 821C 871A 0411 94EA DB02 E193

            F 1 Reply Last reply
            0
            • _ _AnsHUMAN_

              Yeap buddy, I read that , That's why I quoted that the method I propose is not optimized and there could be many other methods of achieving the same. Somethings seem HARD to do, until we know how to do them. ;-) _AnShUmAn_

              S Offline
              S Offline
              Sarath C
              wrote on last edited by
              #6

              Do you know how how a double or float laid in memory? it would be easier using some mask & ing, | ing or <>ing to catch the values. SaRath.
              "It is your attitude, not your aptitude, that determines your altitude - Zig Ziglar." My Blog | Understanding State Pattern in C++

              1 Reply Last reply
              0
              • B Barry Etter

                I need to take a float or double value nand determine how many numbers it has before and after the decimal. Examples: 123.3 -> 3 before and 1 after .12345 -> 0 before and 5 after 123 -> 3 before and 0 after The method has to be extremely fast because it may be executed very often in a high-volume environment. I know I can convert it to a string and search for the decimal, etc., but string functions are very slow. Thanks! Barry Etter

                C Offline
                C Offline
                Cedric Moonen
                wrote on last edited by
                #7

                To find the number of digits before the floating point, you can use the log10 function. You need to round down the result and add 1. For the number of digits after the floating point, I don't have any idea.


                Cédric Moonen Software developer
                Charting control

                F 1 Reply Last reply
                0
                • B Barry Etter

                  I need to take a float or double value nand determine how many numbers it has before and after the decimal. Examples: 123.3 -> 3 before and 1 after .12345 -> 0 before and 5 after 123 -> 3 before and 0 after The method has to be extremely fast because it may be executed very often in a high-volume environment. I know I can convert it to a string and search for the decimal, etc., but string functions are very slow. Thanks! Barry Etter

                  V Offline
                  V Offline
                  Viorel
                  wrote on last edited by
                  #8

                  I think you can investigate the following approach. For the "before" part of positive values:

                  float f;
                  long m = (long)f;
                  int before;
                  
                  if( m == 0) before = 0;
                  else if( m <= 9) before = 1;
                  else if( m <= 99) before = 2;
                  else if( m <= 999) before = 3;
                  else ...
                  

                  and so on according to a maximal value. Hope it is fast enough. For the "after" part, you can try a similar idea, but I am afraid it will be some problems related to imprecise representation of decimal float numbers in binary format, but such issue you will see in case of string-convertion-based method too. -- modified at 10:35 Wednesday 28th June, 2006

                  S 1 Reply Last reply
                  0
                  • B Barry Etter

                    I need to take a float or double value nand determine how many numbers it has before and after the decimal. Examples: 123.3 -> 3 before and 1 after .12345 -> 0 before and 5 after 123 -> 3 before and 0 after The method has to be extremely fast because it may be executed very often in a high-volume environment. I know I can convert it to a string and search for the decimal, etc., but string functions are very slow. Thanks! Barry Etter

                    K Offline
                    K Offline
                    kylur
                    wrote on last edited by
                    #9

                    double x(123.3) ceil(log10(x)) => 3 ie the # digits left of decimal. I'm still working of # digits right of decimal... Regards, Kylur

                    T 1 Reply Last reply
                    0
                    • V Viorel

                      I think you can investigate the following approach. For the "before" part of positive values:

                      float f;
                      long m = (long)f;
                      int before;
                      
                      if( m == 0) before = 0;
                      else if( m <= 9) before = 1;
                      else if( m <= 99) before = 2;
                      else if( m <= 999) before = 3;
                      else ...
                      

                      and so on according to a maximal value. Hope it is fast enough. For the "after" part, you can try a similar idea, but I am afraid it will be some problems related to imprecise representation of decimal float numbers in binary format, but such issue you will see in case of string-convertion-based method too. -- modified at 10:35 Wednesday 28th June, 2006

                      S Offline
                      S Offline
                      Sarath C
                      wrote on last edited by
                      #10

                      can't we use mod (%) instead? SaRath.
                      "It is your attitude, not your aptitude, that determines your altitude - Zig Ziglar." My Blog | Understanding State Pattern in C++

                      V 1 Reply Last reply
                      0
                      • C Cedric Moonen

                        To find the number of digits before the floating point, you can use the log10 function. You need to round down the result and add 1. For the number of digits after the floating point, I don't have any idea.


                        Cédric Moonen Software developer
                        Charting control

                        F Offline
                        F Offline
                        Francesco Aruta
                        wrote on last edited by
                        #11

                        Cedric Moonen wrote:

                        For the number of digits after the floating point, I don't have any idea.

                        well you can do the same... just multiply the initial number by 10 ... F. TBEditor: a pandapowered app!

                        1 Reply Last reply
                        0
                        • S Sarath C

                          can't we use mod (%) instead? SaRath.
                          "It is your attitude, not your aptitude, that determines your altitude - Zig Ziglar." My Blog | Understanding State Pattern in C++

                          V Offline
                          V Offline
                          Viorel
                          wrote on last edited by
                          #12

                          Sarath.can't we use mod (%) instead?

                          I suppose it is not faster.

                          1 Reply Last reply
                          0
                          • K krmed

                            For the number of digits before the decimal, you could use int iNumBefore = 0; iNumBefore = 1 + (int)(log10(x)); where x is your value As for the number of digits after, I don't have any quick ideas on that, but as you say, you could convert to a string (although you might get different results because of the precision of doubles) and then find the decimal. Hope that helps. Karl - WK5M PP-ASEL-IA (N43CS) PGP Key: 0xDB02E193 PGP Key Fingerprint: 8F06 5A2E 2735 892B 821C 871A 0411 94EA DB02 E193

                            F Offline
                            F Offline
                            Francesco Aruta
                            wrote on last edited by
                            #13

                            krmed wrote:

                            As for the number of digits after, I don't have any quick ideas on that, but as you say, you could convert to a string (although you might get different results because of the precision of doubles) and then find the decimal.

                            int iNumAfter = 0; iNumAfter = 1 + (int)(log10(x*10)); Could it works? F. TBEditor: a pandapowered app!

                            1 Reply Last reply
                            0
                            • K kylur

                              double x(123.3) ceil(log10(x)) => 3 ie the # digits left of decimal. I'm still working of # digits right of decimal... Regards, Kylur

                              T Offline
                              T Offline
                              Tnarol
                              wrote on last edited by
                              #14

                              Be careful of the behaviour if x = 0 when using "log10". For the number of digits after "." I think you're going to have some problems, simply because the computer representation of floats and doubles of numbers do not exactly correspond to the value you gave. For instance it could happen that 123.3 actually corresponds to 123.29999999999999 as soon as it is stored as a float. So trying to guess the number of digits after "." makes no sense. You could maybe get around this if you limit the possible amount of decimal numbers to a well chosen value.

                              1 Reply Last reply
                              0
                              • B Barry Etter

                                I need to take a float or double value nand determine how many numbers it has before and after the decimal. Examples: 123.3 -> 3 before and 1 after .12345 -> 0 before and 5 after 123 -> 3 before and 0 after The method has to be extremely fast because it may be executed very often in a high-volume environment. I know I can convert it to a string and search for the decimal, etc., but string functions are very slow. Thanks! Barry Etter

                                C Offline
                                C Offline
                                Chris Losinger
                                wrote on last edited by
                                #15

                                you're going to run into floating-point precision errors, unless you round numbers to a maximum number of decimal places. ex. you're going to come across something like 1.9999999999... Cleek | Image Toolkits | Thumbnail maker

                                1 Reply Last reply
                                0
                                • B Barry Etter

                                  I need to take a float or double value nand determine how many numbers it has before and after the decimal. Examples: 123.3 -> 3 before and 1 after .12345 -> 0 before and 5 after 123 -> 3 before and 0 after The method has to be extremely fast because it may be executed very often in a high-volume environment. I know I can convert it to a string and search for the decimal, etc., but string functions are very slow. Thanks! Barry Etter

                                  Z Offline
                                  Z Offline
                                  Zac Howland
                                  wrote on last edited by
                                  #16

                                  String operations are your best bet for the most accuracy and flexibility (easy to control the number of significant figures). Since you don't want to go that route, this might get you started: To count left side of decimal unsigned long countLeftOfDecimal(double x) { if (1 > abs(x)) { return 0; // x is between -1 and 1 } else if (1 == abs(x)) { return 1; // x is either -1 or 1 } else { return ceil(log10(abs(x))); } } unsigned long countRightOfDecimal(double x) { long y = x; // truncate the decimal double x1 = x - (double)y; // keep only the decimal long count = 0; while (0.0 != x1) { double x2 = x1 * 10.0; // move the decimal 1 place y = x2; // truncate the decimal x1 = x2 - y; // keep only the decimal ++count; } return count; } Keep in mind that you will run into problems when you have numbers like 1.99999999999... with this algorithm -- which is why converting to a string for counting significant figures is a better solution, and may actually be faster than any non-string solution you come up with that doesn't have problems with infinite repeating decimals. If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac -- modified at 15:16 Wednesday 28th June, 2006

                                  1 Reply Last reply
                                  0
                                  • _ _AnsHUMAN_

                                    use CString's Format function CString strFloat; strFloat.Format("%f",myfloatvalue); //Search for . strFloat.Find(); and then use CString's Left() and Right() methods This code is not optimized. It's just one way of doing this Somethings seem HARD to do, until we know how to do them. ;-) _AnShUmAn_

                                    J Offline
                                    J Offline
                                    Jorgen Sigvardsson
                                    wrote on last edited by
                                    #17

                                    He specifically said that he did not want to convert to and from strings.

                                    -- 100% natural. No superstitious additives.

                                    1 Reply Last reply
                                    0
                                    • B Barry Etter

                                      I need to take a float or double value nand determine how many numbers it has before and after the decimal. Examples: 123.3 -> 3 before and 1 after .12345 -> 0 before and 5 after 123 -> 3 before and 0 after The method has to be extremely fast because it may be executed very often in a high-volume environment. I know I can convert it to a string and search for the decimal, etc., but string functions are very slow. Thanks! Barry Etter

                                      R Offline
                                      R Offline
                                      Rilhas
                                      wrote on last edited by
                                      #18

                                      I don't think there is an easy solution for this without passing the real values to a string. This is mainly due to the fact that the real numbers may have an exact representation as decimal and an inexact representation as native. And, of course, vice-versa. For example, float 0.2 has an inexact native representation. The exact representation is 0.200000002980232. But the resolution present in a float is not enough for all the decimals. This just means that you probably won't have much luch analysing the bits in the float (or double). Their memory layout can be found in http://www.psc.edu/general/software/packages/ieee/ieee.html[^]. In any case, finding the values you want by using strings or not, this can always get complicated: float f=0.00031233478376329384729344178300483284723740923762730534976862e7f; double d=f; printf("f=%f, d=%.15g", f, d); This code compiles, but due to the lack of precision in the floating point representations the results are not what one would expect. So, the only fast solution I can imagine involves the assumption that you have not that many number variations, they are always around zero (controlled exponent), and that you do not have rounding errors. With these assumptions you could build a fast look up table. For example, assume that you will have numbers between -999.99 and +999.99. This results in 199998 diferent numbers plus the zero, i.e., 199999. So you could program the following algorithm: // build table float f; int i; i=0; for(f=-999.99; f<=-999.99; f+=0.01f) { table[i].left=ComputeLeftByUsingStrings(f); table[i].right=ComputeRightByUsingStrings(f); i++; } // get the left/right values for float f fast! f*=100.0f; // shift so that the smallest decimal becomes an integer int i=(int)f; // convert to int to use as offset to the table i+=99999; // correct the start offset to start at 0 for the most negative number int left=table[i].left; // left will contain the number of characters to the left int right=table[i].right; // right will contain the number of characters to the right I hope this helps! Rilhas

                                      1 Reply Last reply
                                      0
                                      Reply
                                      • Reply as topic
                                      Log in to reply
                                      • Oldest to Newest
                                      • Newest to Oldest
                                      • Most Votes


                                      • Login

                                      • Don't have an account? Register

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • World
                                      • Users
                                      • Groups