Welcome to the Parallax Discussion Forums, sign-up to participate.

JBWolf
Posts: **336**

in Propeller 1

I am having a terrible time time to figure out how to work with decimals.

I purchased one of the MS5607 Altimeters, which came with example code... but its completely formatted to displaying string output.

I can get a value from the altimeter driver, which returns a non-decimal (i.e. 87594 = 875.94ft), by doing this:

CM := alt.altitude(alt.average_press) ' Get the current altitude in cm, from new average local pressure.

ST := alt.convert(CM, alt#FEET) ' Record starting elevation, use alt.convert to change CM to FT

but if I try to divide by 100 or multiply by 0.01, it drops the decimal value and 87594 becomes 875 instead of 875.94.

I have tried using local var, byte, long and float.... I revisited the PEkit book and tried floatmath with fmath.fmul and fmath.fdiv. but those return a crazy value.

I could just use the non-decimal value, but I find it odd that I cannot work with or display a remainder.

What am I missing?

I purchased one of the MS5607 Altimeters, which came with example code... but its completely formatted to displaying string output.

I can get a value from the altimeter driver, which returns a non-decimal (i.e. 87594 = 875.94ft), by doing this:

CM := alt.altitude(alt.average_press) ' Get the current altitude in cm, from new average local pressure.

ST := alt.convert(CM, alt#FEET) ' Record starting elevation, use alt.convert to change CM to FT

but if I try to divide by 100 or multiply by 0.01, it drops the decimal value and 87594 becomes 875 instead of 875.94.

I have tried using local var, byte, long and float.... I revisited the PEkit book and tried floatmath with fmath.fmul and fmath.fdiv. but those return a crazy value.

I could just use the non-decimal value, but I find it odd that I cannot work with or display a remainder.

What am I missing?

## Comments

336a= 12345

b=0.01

c=a*b

pst.dec(c)

1,981336just havent figured out how to work with and display decimals.

2,465Edit: Oh, yeah! Forgot about the left padding zero(es) for the fractional part. See the comments below for the proper solution.

1,380To add or subtract fixed-point numbers, they need to have the same multiplier - scale one or both until they do. To multiply two numbers with a multiplier of 100, say 12.34 (stored as 1234) and 23.4 (stored as 2340), you multiply them (1234 * 2340 = 2887560) to get a number with a multiplier that's the product of the two input numbers: (12.34 * 100) * (23.40 * 100) = (288.7560 * 10000). If you want the result to have the original multiplier, you just divide the 2887560 by 100, which gives 28875 (printed as 288.75, which is the (truncated) correct answer). Watch out for overflow - divide before multiplication if you need to. You can split the division into two - one before, one after - to maximize precision while avoiding overflow.

EDIT: use Spin modulus operator

336I cannot get any function out of a percentage sign... i.e.

x:=x%100

pst.dec((x % 100))

1,380EDIT: (My copy of) the PST object doesn't have a way to print fixed-width decimal values, so you'll either have to prepend a "0" if ||x // 100 < 10, or you could just do the two digits manually separately:

Note the ||absolute value operators. You need these, or negative numbers won't display properly.

It might be a good idea to make a function to do this for you, since the chances are that you'll be doing it in multiple places.

6,719I have a product that displays values to two decimal points. For it I have a little method called dec2() that ensures I get a 2-digit (with leading zero) value.

Easy-peasy. Now I would do this: and get the correct display of 10.06.

6,492A main loop to read and display pressure and temperature, lined up in columns with 2 decimal places becomes:

3,39222,651It expands upon the Library's SimpleNumbers object and provides methods for fixed-point decimal conversions to strings. For example, to print 1234 as 12.34, you might write:

where

seris the serial output object, likeParallax Serial Terminal, andnumrefers to my object. This prints 12.34 in a field 6 spaces wide, with 2 digits after the decimal point.SimpleNumbersPlusincludes a buffer that allows multiple string results before the buffer has to get reused.I believe that including methods like

decandhexin I/O routines is redundant. It's better if output drivers were limited tocharandstrand that numerical conversions happened in external objects that convert numbers to strings in various desired formats.-Phil

336the // worked beautifully for basic display.

Many other great responses here, I'll be saving this thread. thanks much guys!

now if I can just figure out why the altimeter keeps flickering between 0.00ft and exactly 0.23ft while sitting still

6,492Phil,

About redundancy. On the side of including those methods in the I/O objects, I always need to debug results, most often to a serial terminal and in fixed point decimal, so I want the quickest path without additional objects and extra keystrokes. Often that suffices. In more complex projects that involve sending data to different end points (terminal, wireless, LCD, TV, SD card etc.) it clearly becomes more efficient to keep the numerical conversions as a separate object. In that case the unused methods in the I/O object can be excised or simply not compiled per bst or PropellerIDE.

I wrote my own separate object, I call "recordBuilder", that acts like your buffer to build up fields into a record . (We like to invent our own wheels!). It includes the numerical methods in a range of formats, with field separators and means to insert status codes like NA and OL. The snippet I posted above has the handler for correct display of NEGX, but in recordBuilder, NEGX passed in from sensor driver converts to "NA" and POSX converts to "OL".

6,492