# Floating point number to 1 decimal place

Discussion in 'Programmer's Corner' started by portreathbeach, Jul 2, 2014.

1. ### portreathbeach Thread Starter Active Member

Mar 7, 2010
143
5
I have a floating point number and want to round it to 1 decimal place and also want to display the .0 if it ends up a whole number. I then want to make this into a string to use in another function to display it on my LCD.

So far I have this:

Code ( (Unknown Language)):
1.     uint16 wholeNumber = trunc(val);                        // truncate the value to get the whole number
2.
3.     uint16 afterDP = round((val*10) - (wholeNumber*10));    // get 1 DP by rounding (val*10 - wholeNumber*10)
4.
5.     uint8 char1 = wholeNumber/100;
6.
7.     uint8 char2 = (wholeNumber - (char1*100))/10;
8.
9.     uint8 char3 = wholeNumber-(char1*100)-(char2*10);
10.
This gives me the hundreds, tens and units and the decimal place numbers into char1, char2, char3 and afterDP.

To get the ASCII values, I will add 0x30 to each character.

I already have a function I can call to display a string to my screen, the function is:

Code ( (Unknown Language)):
1. void displaySmallString(uint8 x, uint8 y, char *characters);
2.
I can call it by:

Code ( (Unknown Language)):
1. displaySmallString(10,10, "Hello");
2.
But what I want to do is be able to call the function with a string that is made up of the characters; char1, char2, char3, a decimal point, afterDP

Oh, I am using XC8 compiler for a PIC

2. ### MrChips Moderator

Oct 2, 2009
12,621
3,451
You can pack the ASCII characters into the string one at a time:

Code ( (Unknown Language)):
1.
2.
3. char s[10];
4.
5. s[0] = char1;
6. s[1] = char2;
7. s[2] = char3;
8. s[3] = '.';
9. s[4] = afterDP;
10. s[5] = 0;
11.
12.

3. ### portreathbeach Thread Starter Active Member

Mar 7, 2010
143
5
Hi,

That is pretty much what I have also:

char str[5];

Code ( (Unknown Language)):
1.     str[0]= char1; + 0x30;
2.     str[1]= char2; + 0x30;
3.     str[2]= char3; + 0x30;
4.     str[3]= (".");
5.     str[4]= afterDP + 0x30;
I'm adding 0x30 to make it the equivalent ASCII character code.

The problem is, how do I call my function to display this, it will not accept:

Code ( (Unknown Language)):
1.  while (*str){
2.     displaySmallChar(10, 10, *str++);
3. }

4. ### MrChips Moderator

Oct 2, 2009
12,621
3,451
Try

Code ( (Unknown Language)):
1.
2. displaySmallString(10,10, &str[0]);
3.
BTW, what we are discussing is called fixed point arithmetic, not floating point arithmetic.

5. ### MrChips Moderator

Oct 2, 2009
12,621
3,451

Code ( (Unknown Language)):
1.
2. str[3]= (".");
3.
use:

Code ( (Unknown Language)):
1.
2. str[3]= 0x2E;
3.

6. ### portreathbeach Thread Starter Active Member

Mar 7, 2010
143
5
Yep, that's done it.

But is there not a way to put the characters into a kind of string? Like, when I call the function with "Hello". Instead of having to call the function 5 times

7. ### MrChips Moderator

Oct 2, 2009
12,621
3,451
After you have packed the single characters into a string you now have a single string.
Call displaySmallString( ) once.

8. ### djsfantasi AAC Fanatic!

Apr 11, 2010
2,899
870
Small point, but in your code you have a typo. It should look like:
Code ( (Unknown Language)):
1.     str[0]= char1 + 0x30;
2.     str[1]= char2 + 0x30;
3.     str[2]= char3 + 0x30;
4.     str[3]= (".");
5.     str[4]= afterDP + 0x30;
in the first three lines, the first semi-colon is incorrect. Remove it.

9. ### portreathbeach Thread Starter Active Member

Mar 7, 2010
143
5
OK. All working now apart from when I pass the string into the function, I have a

while (*character++){
.....calls a function to do something
}

The problem is that the array needs a null on the end I think but I can't get it to work. I tried putting a '\0' on the end but it didn't work.

10. ### djsfantasi AAC Fanatic!

Apr 11, 2010
2,899
870
Add one more array element and set it to 0 (not\0)
Code ( (Unknown Language)):
1. str[5]=0;

11. ### portreathbeach Thread Starter Active Member

Mar 7, 2010
143
5
That doesn't work either.

As some of the characters passed in could actually be a 0. How does it determine the null 0 at the end from an actual 0 that you may want.

The while(*chacters++){
}

keeps going past the end of the array and then gets random characters and the program jumps all over the place.

12. ### portreathbeach Thread Starter Active Member

Mar 7, 2010
143
5
If I send "hello" to the lcd display function, the

while (*characters){

}

stops after the last character, but when sending it my array I made it doesn't know where the end of it is.

So when sending "hello" what is telling it what is the end?

13. ### MrChips Moderator

Oct 2, 2009
12,621
3,451
No, No, No.

You have to learn how characters are packed in a string. This is the correct code.

Code ( (Unknown Language)):
1.
2. str[5] = 0;
3.
If this does not work then you are doing something else incorrectly.

Avoid trying to work around a problem without understanding the problem. Do it right in the first place.

The C compiler puts a NUL character at the end of the string "hello".

What is the ASCII for NUL character? It is zero, not the numeral zero.

14. ### MrChips Moderator

Oct 2, 2009
12,621
3,451
And another thing, '0' is not the same as "0".

'0' is a character.

"0" is a string.

15. ### THE_RB AAC Fanatic!

Feb 11, 2008
5,435
1,305
I use this;
Code ( (Unknown Language)):
1.
2. str[3]= ('.');
3.
Which gives the the benefit of ASCII char code readability, but does not carry the trailing zero caused by "" ASCII string tags.

ErnieM likes this.
16. ### portreathbeach Thread Starter Active Member

Mar 7, 2010
143
5
OK.

Please can someone tell me why the first time callStringToSend is called, it works, but when I call it with the contents of 'buf', it keeps going past the end of the string.

Code ( (Unknown Language)):
1.
2. void display(char *character){
3. .... the code to display something on my screen
4. }
5.
6.
7. void takeStringToSend(char *ch){
8.    while (*ch){
9.    display (*ch++)
10. }}
11. }
12.
13.
14.
15. void main{
16.
17. char buf[5];
18. buf[0] = 0x31;     //ASCII 1
19. buf[1] = 0x32;;     //ASCII 2
20. buf[2] = 0x33;;     //ASCII 3
21. buf[3] = 0x2E;;     //ASCII .
22. buf[4] = 0x34;;     //ASCII 4
23. buf[5] = 0;
24.
25.
26. takeStringToSend("123.4");
27.
28. takeStringToSend(buf);
29.
30. }
Also, I still don't understand the null value at the end. What if you had an array where you wanted to store a 0 in it? How does it differentiate between a null and a 0.

Oct 2, 2009
12,621
3,451
Try

char buf[6];

18. ### MrChips Moderator

Oct 2, 2009
12,621
3,451
No one needs to store zero in a character string.

The ASCII character for the numeral 0 is 48 or 0x30.

19. ### ErnieM AAC Fanatic!

Apr 24, 2011
7,433
1,623
QFT.

Note the single quote is used for a single character, while a double quote is used for a zero terminated string.

This is the preferred form as there are no magic numbers here (that are obscure and not obviously correct or incorrect).

A child could tell you what the character is.

20. ### portreathbeach Thread Starter Active Member

Mar 7, 2010
143
5
I'll have a go when I get home.

What would happen if you actually wanted an array of numbers. If one of the numbers stored in the array way 0, would the C routine that has the: while(*characters) nit think that it was the end of the array when it got to a number 0 which you may actually want stored in the array.