Jump to content

How to split a floating number into 4 individual digits??? (Arduino)

grimreeper132

How do I split a floating number up into 4 digits, so I can use each one individually so I can display using LEDs. The number I am getting are 25.12 for example which would relate to 2 Red LEDs, 5 Yellow, 1 white and 2 Blue. I can do the part after getting the numbers into the 4 digits split up. The only way I can think of its through a massively long bit of code of ifs going through all possibilities which just seams stupid and that there is a better way to do it. Any Suggestions welcome.

The owner of "too many" computers, called

The Lord of all Toasters (1920X 1080ti 32GB)

The Toasted Controller (i5 4670, R9 380, 24GB)

The Semi Portable Toastie machine (i7 3612QM (was an i3) intel HD 4000 16GB)'

Bread and Butter Pudding (i7 7700HQ, 1050ti, 16GB)

Pinoutbutter Sandwhich (raspberry pi 3 B)

The Portable Slice of Bread (N270, HAHAHA, 2GB)

Muffinator (C2D E6600, Geforce 8400, 6GB, 8X2TB HDD)

Toastbuster (WIP, should be cool)

loaf and let dough (A printer that doesn't print black ink)

The Cheese Toastie (C2D (of some sort), GTX 760, 3GB, win XP gaming machine)

The Toaster (C2D, intel HD, 4GB, 2X1TB NAS)

Matter of Loaf and death (some old shitty AMD laptop)

windybread (4X E5470, intel HD, 32GB ECC) (use coming soon, maybe)

And more, several more

Link to comment
Share on other sites

Link to post
Share on other sites

Is the value always two integers and two decimals, like the "25.12" you mentioned? Or in other words, is the value always less than 100 and more or equal to 0?

Hand, n. A singular instrument worn at the end of the human arm and commonly thrust into somebody’s pocket.

Link to comment
Share on other sites

Link to post
Share on other sites

Are they always four digits? Then a modulo trick will work:

At the risk of solving homework :P here it is. First multiply by 100, cast to int and then loop over it taking modulus 10 to give you the last digit of the integer.

x = int(x * 100)
while x > 10:
  digit = x % 10
  x = x / 10

 

Crystal: CPU: i7 7700K | Motherboard: Asus ROG Strix Z270F | RAM: GSkill 16 GB@3200MHz | GPU: Nvidia GTX 1080 Ti FE | Case: Corsair Crystal 570X (black) | PSU: EVGA Supernova G2 1000W | Monitor: Asus VG248QE 24"

Laptop: Dell XPS 13 9370 | CPU: i5 10510U | RAM: 16 GB

Server: CPU: i5 4690k | RAM: 16 GB | Case: Corsair Graphite 760T White | Storage: 19 TB

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, WereCatf said:

Is the value always two integers and two decimals, like the "25.12" you mentioned? Or in other words, is the value always less than 100 and more or equal to 0?

No negatives between 0 and 100 (not including 100)

 

1 hour ago, tikker said:

Are they always four digits? Then a modulo trick will work:

At the risk of solving homework :P here it is. First multiply by 100, cast to int and then loop over it taking modulus 10 to give you the last digit of the integer.


x = int(x * 100)
while x > 10:
  digit = x % 10
  x = x / 10

 

It's not homework it's me being a nerd in my own time deciding to do something stupidly pointless cause I can. Also that's not arduino code.

 

2 hours ago, M.Yurizaki said:

Multiply it by 100 to shift the digits. You can then truncate it to an int and do your magic from there.

Yea, I did that, thanks, and it worked. It took me far too long though to work out that I was getting the digits in reverse order (at least 30 mins, me smurt)

The owner of "too many" computers, called

The Lord of all Toasters (1920X 1080ti 32GB)

The Toasted Controller (i5 4670, R9 380, 24GB)

The Semi Portable Toastie machine (i7 3612QM (was an i3) intel HD 4000 16GB)'

Bread and Butter Pudding (i7 7700HQ, 1050ti, 16GB)

Pinoutbutter Sandwhich (raspberry pi 3 B)

The Portable Slice of Bread (N270, HAHAHA, 2GB)

Muffinator (C2D E6600, Geforce 8400, 6GB, 8X2TB HDD)

Toastbuster (WIP, should be cool)

loaf and let dough (A printer that doesn't print black ink)

The Cheese Toastie (C2D (of some sort), GTX 760, 3GB, win XP gaming machine)

The Toaster (C2D, intel HD, 4GB, 2X1TB NAS)

Matter of Loaf and death (some old shitty AMD laptop)

windybread (4X E5470, intel HD, 32GB ECC) (use coming soon, maybe)

And more, several more

Link to comment
Share on other sites

Link to post
Share on other sites

2 hours ago, M.Yurizaki said:

Multiply it by 100 to shift the digits. You can then truncate it to an int and do your magic from there.

on another note what does this error message mean???

 

Quote

Arduino: 1.8.5 (Windows 10), Board: "Arduino Due (Programming Port)"

In file included from C:\Users\Grimreeper132\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.11\cores\arduino/Arduino.h:34:0,

                 from sketch\Version_1.ino.cpp:1:

C:\Users\Grimreeper132\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.11\cores\arduino/binary.h:31:12: error: expected unqualified-id before numeric constant

 #define B1 1

            ^

D:\Code\Temperture\Temperture and variable Resistor to LED Output\Version_1\Version_1.ino:48:11: note: in expansion of macro 'B1'

 const int B1=34;

           ^

exit status 1
Error compiling for board Arduino Due (Programming Port).

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
 

 

The owner of "too many" computers, called

The Lord of all Toasters (1920X 1080ti 32GB)

The Toasted Controller (i5 4670, R9 380, 24GB)

The Semi Portable Toastie machine (i7 3612QM (was an i3) intel HD 4000 16GB)'

Bread and Butter Pudding (i7 7700HQ, 1050ti, 16GB)

Pinoutbutter Sandwhich (raspberry pi 3 B)

The Portable Slice of Bread (N270, HAHAHA, 2GB)

Muffinator (C2D E6600, Geforce 8400, 6GB, 8X2TB HDD)

Toastbuster (WIP, should be cool)

loaf and let dough (A printer that doesn't print black ink)

The Cheese Toastie (C2D (of some sort), GTX 760, 3GB, win XP gaming machine)

The Toaster (C2D, intel HD, 4GB, 2X1TB NAS)

Matter of Loaf and death (some old shitty AMD laptop)

windybread (4X E5470, intel HD, 32GB ECC) (use coming soon, maybe)

And more, several more

Link to comment
Share on other sites

Link to post
Share on other sites

3 minutes ago, grimreeper132 said:

on another note what does this error message mean???

It's complaining you're trying to make 1 = 34.

 

When you have a #define preprocessor, the compiler looks for all instances of the first argument and replaces it with the second argument. In the case of #define B1 1, anywhere in the code where there's a B1, the compiler replaces it with 1.

Link to comment
Share on other sites

Link to post
Share on other sites

8 hours ago, grimreeper132 said:

How do I split a floating number up into 4 digits, so I can use each one individually so I can display using LEDs. The number I am getting are 25.12 for example which would relate to 2 Red LEDs, 5 Yellow, 1 white and 2 Blue. I can do the part after getting the numbers into the 4 digits split up. The only way I can think of its through a massively long bit of code of ifs going through all possibilities which just seams stupid and that there is a better way to do it. Any Suggestions welcome.

I'd really recommend rethinking your encoding mechanism for this.  Floating point numbers cannot accurately represent all numbers in their ranges, and using them in calculations can introduce additional error:

 

i.e.  (0.12 - 0.02) is not guaranteed to equal 0.1

and 0.1 cannot be represented accurately by an floating point number.

Link to comment
Share on other sites

Link to post
Share on other sites

12 hours ago, grimreeper132 said:

How do I split a floating number up into 4 digits, so I can use each one individually so I can display using LEDs. The number I am getting are 25.12 for example which would relate to 2 Red LEDs, 5 Yellow, 1 white and 2 Blue. I can do the part after getting the numbers into the 4 digits split up. The only way I can think of its through a massively long bit of code of ifs going through all possibilities which just seams stupid and that there is a better way to do it. Any Suggestions welcome.

Note that on such small microcontrollers, such as AVR used in arduino, floating point is expensive in both program memory used and execution time. Floating point is complex and without any hardware support it has to be completely emulated on these small 8-bit controllers.

 

A common trick to reduce the overhead is to stick to integers but simply multiply by a power of 10 first. For example, say your result of 25.12 is the result of dividing 628 by 25. This could be implemented with integers as 62800 / 25 = 2512. If you need to print this result on a display, you simply print a decimal point in right place. In your case you can simply divide by 1000 to get the red leds, mod 1000 divide by 100 for the yellow leds, and so on.

 

Even if this requires using 32 bit integers it will still be much cheaper then using float.

Link to comment
Share on other sites

Link to post
Share on other sites

11 hours ago, grimreeper132 said:

No negatives between 0 and 100 (not including 100)

 

It's not homework it's me being a nerd in my own time deciding to do something stupidly pointless cause I can. Also that's not arduino code.

 

Yea, I did that, thanks, and it worked. It took me far too long though to work out that I was getting the digits in reverse order (at least 30 mins, me smurt)

I know it's not C/Arduino code. It was just to illustrate the logic.

Crystal: CPU: i7 7700K | Motherboard: Asus ROG Strix Z270F | RAM: GSkill 16 GB@3200MHz | GPU: Nvidia GTX 1080 Ti FE | Case: Corsair Crystal 570X (black) | PSU: EVGA Supernova G2 1000W | Monitor: Asus VG248QE 24"

Laptop: Dell XPS 13 9370 | CPU: i5 10510U | RAM: 16 GB

Server: CPU: i5 4690k | RAM: 16 GB | Case: Corsair Graphite 760T White | Storage: 19 TB

Link to comment
Share on other sites

Link to post
Share on other sites

22 hours ago, grimreeper132 said:

How do I split a floating number up into 4 digits, so I can use each one individually so I can display using LEDs. The number I am getting are 25.12 for example which would relate to 2 Red LEDs, 5 Yellow, 1 white and 2 Blue. I can do the part after getting the numbers into the 4 digits split up. The only way I can think of its through a massively long bit of code of ifs going through all possibilities which just seams stupid and that there is a better way to do it. Any Suggestions welcome.

One simpler encoding might be to have each "number" be an array of bytes, each byte representing whichever color. The trick here is, since there are only four colors, this is one 32 bit integer, and so you can do bulk math on the whole value by taking it as an integer, and piecemeal operations by working with the individual bytes.

To get the individual bytes out of the integer you can use bitshifting. For example, if you want the highest byte you can bitshift right 8*3 bits, to get the lowest byte you will first bit shift left 8*3 bits and then bit shift right 8*3 bits. To get a value in between you will bitshift left 8*n and then right 8*3 bits, where n is the non zero based index of the byte you want to get out of the integer.

Another solution is to use bitwise XOR, a bitmask, and a short decision tree to get the bytes out that you want. In both methods I will leave you to figure out how to place the modified bytes back into the integer correctly.

To answer your specific question, the easiest method would be to cast it as a string, and then cast the individual characters of the string to ints, do the math, and then do the reverse.

ENCRYPTION IS NOT A CRIME

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×