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. Floating point conversion

Floating point conversion

Scheduled Pinned Locked Moved C / C++ / MFC
help
12 Posts 8 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.
  • S Offline
    S Offline
    Still learning how to code
    wrote on last edited by
    #1

    I am in the process of trying to code the transmission of floating point data over an ethernet cable. I decided to send two bytes, the first with the "whole" part and the second with the "fractional" part (but as an unsigned char). The first byte works fine, but the second (trivial) part is giving me a strange (to me) problem which is driving me nuts - I can't see WHAT I'm getting wrong. Here is the test code:- float flTest = 0.04; float flResult; flResult = flTest * 100; unsigned char ucResult; ucResult = (unsigned char)flResult; flResult ends up as 4.00000 which is correct, but ucResult gives 3 !! If I change flTest to 0.05, ucResult is 4 !! There is clearly a decrementation involved here, but I can't understand why ! I'm sure that when some kind soul explains it, I shall be kicking myself - HARD !!

    Doug

    M L J C S 5 Replies Last reply
    0
    • S Still learning how to code

      I am in the process of trying to code the transmission of floating point data over an ethernet cable. I decided to send two bytes, the first with the "whole" part and the second with the "fractional" part (but as an unsigned char). The first byte works fine, but the second (trivial) part is giving me a strange (to me) problem which is driving me nuts - I can't see WHAT I'm getting wrong. Here is the test code:- float flTest = 0.04; float flResult; flResult = flTest * 100; unsigned char ucResult; ucResult = (unsigned char)flResult; flResult ends up as 4.00000 which is correct, but ucResult gives 3 !! If I change flTest to 0.05, ucResult is 4 !! There is clearly a decrementation involved here, but I can't understand why ! I'm sure that when some kind soul explains it, I shall be kicking myself - HARD !!

      Doug

      M Offline
      M Offline
      Michael_Davies
      wrote on last edited by
      #2

      Hate float, try decimal. every time I have used float, the results are unpredictable for what seems like straight forward math, decimal behaves itself.

      L 1 Reply Last reply
      0
      • S Still learning how to code

        I am in the process of trying to code the transmission of floating point data over an ethernet cable. I decided to send two bytes, the first with the "whole" part and the second with the "fractional" part (but as an unsigned char). The first byte works fine, but the second (trivial) part is giving me a strange (to me) problem which is driving me nuts - I can't see WHAT I'm getting wrong. Here is the test code:- float flTest = 0.04; float flResult; flResult = flTest * 100; unsigned char ucResult; ucResult = (unsigned char)flResult; flResult ends up as 4.00000 which is correct, but ucResult gives 3 !! If I change flTest to 0.05, ucResult is 4 !! There is clearly a decrementation involved here, but I can't understand why ! I'm sure that when some kind soul explains it, I shall be kicking myself - HARD !!

        Doug

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #3

        There is no decrementation, you just need to understand What Every Computer Scientist Should Know About Floating-Point Arithmetic[^]. What you should do to transfer the data (via serial or internet) is to transfer the exact bytes of the data, rather than trying to convert them to something else. So take the address of the number, cast that to an unsigned char* and send the four bytes thus pointed at. This will ensure that your receiver will get the exact data that you send.

        1 Reply Last reply
        0
        • M Michael_Davies

          Hate float, try decimal. every time I have used float, the results are unpredictable for what seems like straight forward math, decimal behaves itself.

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          Float (and double) do exactly what they are supposed to do. The problem is that too many users do not understand how to use it.

          M 1 Reply Last reply
          0
          • S Still learning how to code

            I am in the process of trying to code the transmission of floating point data over an ethernet cable. I decided to send two bytes, the first with the "whole" part and the second with the "fractional" part (but as an unsigned char). The first byte works fine, but the second (trivial) part is giving me a strange (to me) problem which is driving me nuts - I can't see WHAT I'm getting wrong. Here is the test code:- float flTest = 0.04; float flResult; flResult = flTest * 100; unsigned char ucResult; ucResult = (unsigned char)flResult; flResult ends up as 4.00000 which is correct, but ucResult gives 3 !! If I change flTest to 0.05, ucResult is 4 !! There is clearly a decrementation involved here, but I can't understand why ! I'm sure that when some kind soul explains it, I shall be kicking myself - HARD !!

            Doug

            J Offline
            J Offline
            Jochen Arndt
            wrote on last edited by
            #5

            Still learning how to code wrote:

            flResult ends up as 4.00000 which is correct

            That is not correct. The problem occurs when assigning 0.04 because the binary representation of floating point values can be slightly inexact. In your case flTest will be set to the value 0.0399999991. The following multiplication by 100 will not add another error so that flResult becomes 3.99999991. Because there is no rounding when casting floating point values to integers, the result is 3. To avoid this, you can add 0.5 before casting:

            ucResult = (unsigned char)(flResult + 0.5f);

            Note that the above is for positive numbers only. With negative numbers, 0.5 must be subtracted.

            S 1 Reply Last reply
            0
            • S Still learning how to code

              I am in the process of trying to code the transmission of floating point data over an ethernet cable. I decided to send two bytes, the first with the "whole" part and the second with the "fractional" part (but as an unsigned char). The first byte works fine, but the second (trivial) part is giving me a strange (to me) problem which is driving me nuts - I can't see WHAT I'm getting wrong. Here is the test code:- float flTest = 0.04; float flResult; flResult = flTest * 100; unsigned char ucResult; ucResult = (unsigned char)flResult; flResult ends up as 4.00000 which is correct, but ucResult gives 3 !! If I change flTest to 0.05, ucResult is 4 !! There is clearly a decrementation involved here, but I can't understand why ! I'm sure that when some kind soul explains it, I shall be kicking myself - HARD !!

              Doug

              C Offline
              C Offline
              CPallini
              wrote on last edited by
              #6

              If you need to transmit a float value on the net then do transmit it, that is send its binary representation (e.g 4 bytes for a float, 8 for a double).

              K 1 Reply Last reply
              0
              • C CPallini

                If you need to transmit a float value on the net then do transmit it, that is send its binary representation (e.g 4 bytes for a float, 8 for a double).

                K Offline
                K Offline
                k5054
                wrote on last edited by
                #7

                That's assuming that you have similar processors at both ends of the connection. While big-endian systems are rare these days, they're not non existent. Furthermore, be careful when going between 32-bit and 64-bit systems. On my x86 linux boxes, a long is 4 bytes, whereas on a x86_64 they're 8 bytes, x86 long-double is 12 bytes and x86_64 its 16.

                enhzflepE 1 Reply Last reply
                0
                • K k5054

                  That's assuming that you have similar processors at both ends of the connection. While big-endian systems are rare these days, they're not non existent. Furthermore, be careful when going between 32-bit and 64-bit systems. On my x86 linux boxes, a long is 4 bytes, whereas on a x86_64 they're 8 bytes, x86 long-double is 12 bytes and x86_64 its 16.

                  enhzflepE Offline
                  enhzflepE Offline
                  enhzflep
                  wrote on last edited by
                  #8

                  Are you remembering to take into account the established standard for floating point numbers? The relevant section of the standard, at wikipedia: https://en.wikipedia.org/wiki/IEEE_floating_point#Interchange_formats[^]

                  1 Reply Last reply
                  0
                  • L Lost User

                    Float (and double) do exactly what they are supposed to do. The problem is that too many users do not understand how to use it.

                    M Offline
                    M Offline
                    Michael_Davies
                    wrote on last edited by
                    #9

                    Granted. In this case he is not getting the results he is seeking float may be the problem...

                    L 1 Reply Last reply
                    0
                    • M Michael_Davies

                      Granted. In this case he is not getting the results he is seeking float may be the problem...

                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #10

                      Michael_Davies wrote:

                      float may be the problem.

                      No, the problem is he does not understand how float values are represented in computers.

                      1 Reply Last reply
                      0
                      • J Jochen Arndt

                        Still learning how to code wrote:

                        flResult ends up as 4.00000 which is correct

                        That is not correct. The problem occurs when assigning 0.04 because the binary representation of floating point values can be slightly inexact. In your case flTest will be set to the value 0.0399999991. The following multiplication by 100 will not add another error so that flResult becomes 3.99999991. Because there is no rounding when casting floating point values to integers, the result is 3. To avoid this, you can add 0.5 before casting:

                        ucResult = (unsigned char)(flResult + 0.5f);

                        Note that the above is for positive numbers only. With negative numbers, 0.5 must be subtracted.

                        S Offline
                        S Offline
                        Still learning how to code
                        wrote on last edited by
                        #11

                        First of all, apologies for not replying earlier ! WOW, I didn't think that a few lines of code could provoke so much discussion !!! The technique that I am trying to employ is between a PC and an Arduino (via Com port - actually USB). I used it a few years ago to transfer floating point numbers, but in the OPPOSITE direction and it worked perfectly. Anyway, thank you all for your comments - I am amazed that the "error" is actually in the assignment as pointed out by Jochen. In this particular application, the floating point numbers will be quite small, so I think that I'll have to go for the 4 byte transfer method to maintain accuracy - but I'll be doing a lot of testing !! Thank you all once again !

                        Doug

                        1 Reply Last reply
                        0
                        • S Still learning how to code

                          I am in the process of trying to code the transmission of floating point data over an ethernet cable. I decided to send two bytes, the first with the "whole" part and the second with the "fractional" part (but as an unsigned char). The first byte works fine, but the second (trivial) part is giving me a strange (to me) problem which is driving me nuts - I can't see WHAT I'm getting wrong. Here is the test code:- float flTest = 0.04; float flResult; flResult = flTest * 100; unsigned char ucResult; ucResult = (unsigned char)flResult; flResult ends up as 4.00000 which is correct, but ucResult gives 3 !! If I change flTest to 0.05, ucResult is 4 !! There is clearly a decrementation involved here, but I can't understand why ! I'm sure that when some kind soul explains it, I shall be kicking myself - HARD !!

                          Doug

                          S Offline
                          S Offline
                          S T K
                          wrote on last edited by
                          #12

                          I am not seeing this issue. I get 4 for unResult. Do you have your floating point options set correctly in the compiler? In visual studio, select properties on your C project. Expand the projects setting out for "c/C++->Code Generation" and set the option for "Floating Point Model" to Precise(/fp:precise).

                          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