Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I'd do: fee = amount / 300

More generally: represent the percentage as a rational number, then multiply the amount by the numerator and then divide by the denominator.



With integers this will rounds towards zero. It may be that you only wanted to charge a fee of 1 for an amount of 599 but it would not be unreasonable to want to charge a fee of 2 in this case. Which you could of course fix by adding 299 or maybe 150 before the devision but that makes some pretty hard to understand code.


You can wrap up the logic for doing a division with floor, ceiling, or whatever rounding in a function so you don't get ugly and error prone stuff at each call site.

If you wanted your fees to round up then the actual code would look something like:

  fee = round_up_multiply(amount, 1, 300)


At this point (danbruc correctly covered the first part of my point) you have basically reinvented an arbitrary precision library by storing the numerator, denominator and then having a utility function to choose the exact behavior of the result when converting back to numbers you use for storage and show to the user.

This isn't a fixed point number system, because you are now using a non-fixed point number representation (e.g. two numbers; which can't be represented in fix point because of their repeating nature) to represent your fraction. Trying to get all of that behavior right is more error prone than just using an arbitrary precision library in the first place.


Do you see how you will end up reimplementing a fixed point decimal number type?


Of course. An integer that represents a number of some subdivision of your nominal "one" unit is a fixed-point decimal number type. They're two names for the same thing.

But the other commenter was discussing arbitrary precision arithmetic libraries, not fixed-point decimals.


Of course. An integer that represents a number of some subdivision of your nominal "one" unit is a fixed-point decimal number type. They're two names for the same thing.

And an array of single precision floats is a zero-terminated UTF-8 encoded string. Using an actual fixed point decimal number type is still preferable over going straight to the underlying integer, even if it is only for the easier to read source code with decimal points where they belong instead of having to perform the transformation in your head while reading.

But the other commenter was discussing arbitrary precision arithmetic libraries, not fixed-point decimals.

Fair point.


I take your point, but the nitpicker in me (some might say there's nothing else in there) wants to point out that an array of floats is highly unlikely to be valid UTF-8.

If your language of choice has a good fixed-point decimal library, or you can switch to one that does, then I agree that would definitely be the superior solution.


I take your point, but the nitpicker in me (some might say there's nothing else in there) wants to point out that an array of floats is highly unlikely to be valid UTF-8.

I was afraid of that response and thought about using an integers array and ASCII but it is so nicely abstruse, I could not resist.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: