|
I wouldn't hesitate for a second to give that as the exercise of the week to second year programming students, implmenting the four basic arithmetic operations for rationals.
There is only a small problem: If the denominators are not identical in addition/subtraction, you can trivially find a common denominator by multiplying the two, but in the genral case, it is not the least common denominator. If you use 64 bit integers for the denominator you might delay handling this until the results are to be used (at least for small student level applications), but at some stage you will have to factorize the numerator and denominator, and remove common factors. In principle this is not difficult as long as the problem is of "student size", but Eratosthenes' sieve is not very efficient (certainly not in space!) - you wouldn't want to employ that for every addition or subtraction!
Factors of 2 are easy to get rid of: While both (numerator AND 1) and (denominator ANd 1) are nonzero, shift both right by one bit. This you can do for every basic arithmetic operation (or complex expression). Other factors are worse. If you find it acceptable to do a whole series of division/remainder operations (trying with all prime factors up to the square root of the smaller of numerator and denominator), then the space required is roughly limited to a single read-only table of known primes, but you'll certainly be keeping the division circuitry of the CPU hot .
My recommendation would be to delay the factorization until it is needed for presentation or conversion to other formats. Viewing/interpreting the values through a debugger would be a next to impossible, and you should implement an exception handler removing common factors if an operation would cause the numerator/denominator to overflow the integer format - maybe doing a 2-factor removal as a fast first try, and going on to a series of division operations only if the values are still above a certain overflow risk threshold. If you use 64 bit ints, you might in the worst case have to do divisions for every prime less than 4G; that is quite some operation...
|
|
|
|
|
Not all that hard.
In my MS Computer Science course, All students had to write a compiler for a language that had only integers and rational numbers.
This was before the days of C++, classes, etc.
Not too much of a sweat.
|
|
|
|
|
How did you handle the (least common) denominator problem? Or did you simply ignore it, ignoring the risk that it might overflow? How did you present the results - as if they were floats (through a "(float)numerator/(float)denominator" division) using float output format? Did you do anything to detect common denominators, or did 1/3 + 1/3 end up as 6/9?
|
|
|
|
|
I don't remember the details because it was such a long time ago but I distinctly remember that I did determine the least common denominator for fractions and ensured that all rational numbers were stored in their reduced form.
|
|
|
|
|
While a rational number type has both advantages and disadvantages and we can discuss that forever, it is an undeniable truth that JSON should have had a rational number type, simply because some languages or libraries already support rational numbers and there should exist a portable way for applications using rational numbers to serialize and exchange these with other applications. A rational number that is within the range of a floating point number type can always be "downgraded" to that floating point number type, but the converse is problematic. For example, is the JSON expression [0.67,0.33] an array with the numbers 2/3 and 1/3 ? If not, then what about [0.6666666666666667,0.3333333333333333]? It would have been clear what was meant if we were allowed to write [2/3,1/3].
|
|
|
|
|
Retired.
Again.
Third time.
Got to go out back and make sure the grass is growing.
Going to sit in a rocking chair. Maybe after a few months, I will rock.
Lou
If you can keep your head while those about you are losing theirs, perhaps you don't understand the situation.
|
|
|
|
|
So you have a new full time job as Lawn Inspector? Good for you!
Sent from my Amstrad PC 1640
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
The problem with retirement is that you never get a day off.
I'm pretty sure I would not like to live in a world in which I would never be offended.
I am absolutely certain I don't want to live in a world in which you would never be offended.
Freedom doesn't mean the absence of things you don't like.
Dave
|
|
|
|
|
That is why I went back to work the other 2 times.
If you can keep your head while those about you are losing theirs, perhaps you don't understand the situation.
|
|
|
|
|
theoldfool wrote: Retired. ...
Going to sit in a rocking chair.
Congratulations, rock star!
|
|
|
|
|
Watching the grass grow is tedious work!
Everyone has a photographic memory; some just don't have film. Steven Wright
|
|
|
|
|
Mike Hankey wrote: Watching the grass grow
No World Cup posts!
I'm pretty sure I would not like to live in a world in which I would never be offended.
I am absolutely certain I don't want to live in a world in which you would never be offended.
Freedom doesn't mean the absence of things you don't like.
Dave
|
|
|
|
|
|
Oh sh*t, I'm looking at my first attempt, I have been threatening to retire for the last 3 years but this time I actually changed my contract to working 10 days a month - from home! By the great Ghu I hope it works. I do NOT want to come back to working full time.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
I would have done it sooner but I never got around to commenting my codez.
If you can keep your head while those about you are losing theirs, perhaps you don't understand the situation.
|
|
|
|
|
Hi All,
The useful part of the day has come and gone, I'm too tired to do any more today. I have done what I intended to do and a bit more today (and oh joy the air con has died!) so I am now trying to look busy.
Looking to find secondary sources for components. This allows me to have Altium open and a circuit diagram in front of me with a browser open on a suppliers web page.
|
|
|
|
|
Sorry, it's late - was doing the computers.
Individualist or covert conformist? (10, 2 words)
Whenever you find yourself on the side of the majority, it is time to pause and reflect. - Mark Twain
modified 9-Jul-18 7:04am.
|
|
|
|
|
BLACK SHEEP.
Sent from my Amstrad PC 1640
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
It sure is (and I'd love a pint of it).
Whenever you find yourself on the side of the majority, it is time to pause and reflect. - Mark Twain
|
|
|
|
|
I didn't know it was a beer - I assumed it was a "Guinness + something" like Black Velvet.
Mind you, I could go a cold Guinness right about now ...
Sent from my Amstrad PC 1640
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
I could go anything cold, right now. I'm so hot I could even endure a Carling!
Whenever you find yourself on the side of the majority, it is time to pause and reflect. - Mark Twain
|
|
|
|
|
... because a wise master said:
Do or do not. There is no try.
I think he is right and with the old preprocessor my code would now look like this:
do or do not
{
}
this is why you fail (Exception ex)
{
}
I have lived with several Zen masters - all of them were cats.
His last invention was an evil Lasagna. It didn't kill anyone, and it actually tasted pretty good.
|
|
|
|
|
CodeWraith wrote: Do or do not. There is no try.
How do you know my math teacher from high school?!
"The greatest enemy of knowledge is not ignorance, it is the illusion of knowledge". Stephen Hawking, 1942- 2018
|
|
|
|
|
|
Yoda? I thought the green Muppet guy was Kermit!
I have lived with several Zen masters - all of them were cats.
His last invention was an evil Lasagna. It didn't kill anyone, and it actually tasted pretty good.
|
|
|
|