Sign in to follow this  

represent float as two ints then subtract it by another to get exact value not approximation

This topic is 397 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

i need to represent float as two values int.int

 

then if i have two such floats i need to subtract them but i don't know how.

 

The reason of doing such thing is that i need to precisely subtract one from another like 14.32 - 15.89 => -1.57

 

i am not sure if i could just use these two numbers as single floats then subtract them and  then just round up the result 14.32 - 15.89 =  -1.int(57+0.005)

but then theres what if -1 is 0 etc etc too much complications on fly i need exact numbers not approximations

Share this post


Link to post
Share on other sites
What you’re looking for is fixed point or Q. How wide are your integers there? If possible, try to keep it within a primitive int type, such as a [tt]int64_t[/tt]. Q32.32 or even Q48.16 should be enough, depending on your use case. Otherwise, you may need a datatype that expresses a float in terms of [tt]A + B/scale[/tt]. Be careful because fixed point arithmetic have its own set of problems. It’s much easier to overflow or underflow in fixed point world than it is with typical IEEE 754 floats.

If you need something more precise, there are libraries that already do so: List of Arbitrary-Precision Arithmetic Software. Edited by fastcall22

Share this post


Link to post
Share on other sites

i need something liek this

 

dodawanie-odejmowanie-u%C5%82amk%C3%B3w-

 

i dont even want to implement this but i think ill have too

 

i need to subtract personel days off since for 2 months there is 1.67 dayoff i need to use fkn floats for that 

Edited by WiredCat

Share this post


Link to post
Share on other sites
Have you looked into fix point?

You shouldn't have to worry about this detail unless you require both high accuracy and a very wide range of values. This is more typical of scientific or engineering applications, not games.

Share this post


Link to post
Share on other sites

thats 

 

Have you looked into fix point?

You shouldn't have to worry about this detail unless you require both high accuracy and a very wide range of values. This is more typical of scientific or engineering applications, not games.

thats not a game, its a commercial app - i need to get real values not approximations Dont want to be charged for anything :P

 

mhm BCD im too dumb for that

 

 

funny thing is that i dont know how to subtract these nums like in this picture i gave in second post x_X maturity lel

Edited by WiredCat

Share this post


Link to post
Share on other sites
Fixed point does not approximate. Again, have you actually looked into it? In addition, fastcall22 linked you to arbitrary precision libraries, have you looked at those?

Finally, think about the business process you are replacing. Does it feature a calculator, software or spreadsheet somewhere? Perhaps the business is already used to dealing with the limitations imposed by numeric constraints.

There will always be a limitation, you can invest engineering effort into reducing the number of cases where it will arise but you cannot make the limitations disappear - after all you're working with real computers with finite CPU resources, memory and storage.

Share this post


Link to post
Share on other sites

Fixed-point math is just the binary equivalent of fixed-width math. Imagine you have a spreadsheet where each cell can contain only one digit, and there are eight columns. If you want each row to represent one number, you can choose any column you want to represent the "ones" digit; all those to the left are larger value (tens, hundreds, etc), and those to the right are smaller value (tenths, hundredths, etc). The entire row is called the "mantissa" or "significand", and you choose a fixed point in the representation (hence the name) to be the decimal point in the number it represents.

 

Ignoring signs and overflows, basic arithmetic is nearly identical on fixed-point math of arbitrary "ones" alignment as it is on fixed-point math where there are no fractional digits (e.g. all fixed-width numeric representations, such as 32-bit integers). Addition/subtraction; just sum or subtract the significands. Multiplication; multiply the significands, then shift the significand down to align the result's (virtual) decimal point with the original values' (virtual) decimal point. Work it out in long-form arithmetic on paper, and you should start to see the resemblance.

Share this post


Link to post
Share on other sites

i need to get real values not approximations ....  i need to subtract personel days off since for 2 months there is 1.67 dayoff i need to use fkn floats for that 

 

 

Then you've already lost.

 

It looks like you've got 10 days of each year, but 10 days / 6 months, the amount you get in two months, is 1.66666... repeated forever, not 1.67.

 

Before you got there somebody artificially added rounding to your system at two decimal digits.

 

 

 

 

You will need to accept that what you describe is not possible, real values are ALWAYS approximations, at the very least there is ALWAYS error in the last place which cannot be avoided.

 
Artificial systems (like money, or your time off example) have a fixed precision.  For many currency systems that means exactly two digits beyond the decimal point.  Values smaller than the decimal point are rounded according to various rules.  For example, some calculations require performing all the operations and then rounding to the nearest even number.  Other calculations require doing only a single operation and then performing the rounding to nearest even number after every operation.  Note that the rounding that occurs introduces error in the last place.  If you are applying tax or an interest rate or a sale cost, and the math results in a fraction smaller than one cent, or smaller than one pence, or smaller than whatever the smallest currency unit is, then there is error in the last place.
 
Also with money, when converting from one currency to another currency, not all currencies have the same precision.  Looking up exchange rates, one US cent is currently about 0.07 Chinese Yuan.  If you were exchanging currency and someone had 0.08 Yuan it would probably be rounded down to one cent, but with banker's rounding might be rounded to two cents.  Similarly if they had 0.06 Yuan it might get rounded to one cent or with banker's rounding, rounding to zero cents.  In each case there is error in the last place.
 
 
We arbitrarily limit the precision all the time.  Normally that means measuring to the nearest centimeter, rounding to the nearest hundredth or thousandth, or whatever makes sense for the system. In an example of measuring height, you might measure your height and then round to 172 cm.  But other people might want greater accuracy, perhaps 172.2 cm (or the same expressed as 1722 mm).  While unlikely for a human height measurement, there are measurements people take that are accurate to micrometers, and even some measures accurate down to nanometer scale.  Very rarely, such as those in computer architecture research, they reach sub-nanometer scale. About 0.2nm is the size of a silicon atom, like those made in IBM's rather cool Boy And His Atom movie... Yet even then the size of 0.2nm is an approximation, rounded off at one tenth of a nanometer.  No matter the scale we use, there is still some error in the last place.
 
There is ALWAYS error.  No matter what numeric system we use or what precision we specify, whenever we use math to represent physical things, or when we use math to do arbitrary operations on currency and other systems, we have many sources of error of precision.
 

 

i need to precisely subtract one from another like 14.32 - 15.89 => -1.57

 
That breaks down in the math.

 

Can a person take a third of a day off?  Is that subtracting 0.333333333333333333333... repeated forever?  Or is that subtracting 0.33?  Or will it do like many payroll systems and only allow half-day or quarter-day increments?

 

How does the time accumulate?  Does it add 0.83 days of accumulated time every month? Or 0.833333 days per month?  What if months are different lengths, do they accumulate the same amount in February with 28 or 29 days as they do in January with 31 days?  

 

Or maybe they've got a two week pay cycle and accumulate approximately 0.3846... every two weeks?  Does that apply if they worked just one hour in that two week block? Do the same values apply if they put in massive overtime, working 140 hours over the same two weeks? The person who put in a fraction of one day gets exactly the same value as the person who puts in roughly double the amount of hours worked?

 

Or maybe they get 0.04 accumulated for every full day they work. Or maybe 0.005 for every hour they work?

 

 

 

You need to figure out the rules involved for your business app.  

 

Once you've got it, floating point has enough precision for you.  Floating point has six decimal digits of precision when passing back and forth to decimal values.  So you can have xxx.xxx and still be fully in range of a float for both display and data entry.  That gives about two years of accumulated time off, which will be far outside the range someone getting 10 days per year will ever accumulate during their life, as they aren't going to work for the company for a century without missing a day.  

 

 

 

After you've struggled with it for a while, you'll eventually realize you can use a floating point value and print it with two decimal digits of precision.  

Share this post


Link to post
Share on other sites

There's three standard approaches to the problem here:

 

1. Redefine the units so there aren't any decimals, and use a sufficiently large integer type. For example don't store time as 0.3333333... days. Use 8 hours, or 480 minutes, or 28800 seconds, etc. The same goes for currency values - don't store it as $12.34 - store it as 1234 cents instead. Some languages have special decimal types for this.

 

2. Use an arbitrary precision maths library, that will give you enough accuracy for the operations you care about. This can be fully exact for basic operations on rational numbers. Of course infinite precision can also mean infinite memory and performance costs.

 

3. Decide that a standard floating point type is good enough, and use it. If you're worrying about precision then double is probably what to go for - it has about 15 decimal digits of precision. If you're making a computer game then float (~7 digit precision) should be good enough for almost everything (one significant exception is for total elapsed game time).

Share this post


Link to post
Share on other sites

 

 

1. Redefine the units so there aren't any decimals, and use a sufficiently large integer type. For example don't store time as 0.3333333... days. Use 8 hours, or 480 minutes, or 28800 seconds, etc. The same goes for currency values - don't store it as $12.34 - store it as 1234 cents instead. Some languages have special decimal types for this.

 

 

 

Genius_meme.jpeg

 

 

LOL! thats exactly what i should do!

Share this post


Link to post
Share on other sites

If you're using C# you can use the decimal class, which by my guess is BCD since it allows for exact decimals.

You seem pretty confused between fixed width decimal (an integral type used to represent numbers to a fixed degree of precision over a fixed range, as opposed to 'float' decimals which have a fixed degree of precision over a varying range) and BCD, a binary encoding of two numeric characters in a single byte.
A fixed decimal would be something like 123.45, a float is 1.2345e2, and BCD would be "12".

Share this post


Link to post
Share on other sites

1. Redefine the units so there aren't any decimals, and use a sufficiently large integer type. For example don't store time as 0.3333333... days. Use 8 hours, or 480 minutes, or 28800 seconds, etc. The same goes for currency values - don't store it as $12.34 - store it as 1234 cents instead. Some languages have special decimal types for this.

 

These are examples of radix notation and fixed point

Share this post


Link to post
Share on other sites

You seem pretty confused between fixed width decimal (an integral type used to represent numbers to a fixed degree of precision over a fixed range, as opposed to 'float' decimals which have a fixed degree of precision over a varying range) and BCD, a binary encoding of two numeric characters in a single byte. A fixed decimal would be something like 123.45, a float is 1.2345e2, and BCD would be "12".

Not confused.... like I said it was a guess.  And as far as BCD goes I didn't mean straight BCD, I was imagining something along the lines of a string of BCD with a floating decimal encoded into one of the unused states. 

Share this post


Link to post
Share on other sites

This topic is 397 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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

Sign in to follow this