Beefy Boxes and Bandwidth Generously Provided by pair Networks Frank
No such thing as a small change
 
PerlMonks  

Decimals to fractions

by oko1 (Deacon)
on Jul 16, 2012 at 12:43 UTC ( #982023=CUFP: print w/ replies, xml ) Need Help??

I'd imagine there's a module out there to do this, but I just threw this together in a couple of minutes. Besides, it was fun. :)

There are lots of times that I need to figure out this kind of stuff - I live on a boat and ride a motorcycle, so I'm always wrenching on something. In fact, I did something like this many, many years ago, but somehow managed to lose track of it... actually, I recall that implementation being quite a naive one (I was just starting to learn programming then.) Hope it's of use to others as well!

#!/usr/bin/perl # By: Ben Okopnik <ben@okopnik.com>, 07:45 2012-07-16 # Finds nearest "tape measure" fraction for a given decimal use warnings; use strict; die "Usage: ", $0 =~ /([^\/]+)$/, " <number> [tolerance]\n" unless @ARGV && $ARGV[0] =~ /^(\d+)?(\.\d+)$/; # Yep, positives o +nly :) my $int = $1 || 0; my $dec = $2; die "No mantissa\n" unless $dec > 0; die "Not a reasonable tolerance\n" if $ARGV[1] && $ARGV[1] !~ /^0?\.\d+$/; my $tolerance = $ARGV[1] || .001; # 1 mil is the default my $denom = 2; { for my $num (1 .. $denom - 1){ die $int + $dec, " is equal to $int $num/$denom (+/-$tolerance +)\n" if abs($dec - $num / $denom) <= $tolerance; } $denom *= 2; redo; }
-- 
I hate storms, but calms undermine my spirits.
 -- Bernard Moitessier, "The Long Way"

Comment on Decimals to fractions
Download Code
Re: Decimals to fractions
by Athanasius (Prior) on Jul 16, 2012 at 14:43 UTC
    I'd imagine there's a module out there...

    For the record, there’s a core module Math::BigRat which handles rational numbers of arbitrary size, and converts to and from floats, etc. See:

    Athanasius <°(((><contra mundum

Re: Decimals to fractions
by tobyink (Abbot) on Jul 16, 2012 at 15:04 UTC

    This one has no tolerance - it should always be exact (except in the case of overflowing the bounds of integer arithmetic for your architecture).

    use 5.010; say fraction_for_decimal($_) for qw( 0.3456 1.251 -0.1 -0.25 ); sub fraction_for_decimal { my $decimal = shift; my $mult = 10 ** length [ split m{[.]}, $decimal ]->[1]; my ($num, $den) = (int($decimal * $mult), $mult); my $hcf = _hcf($num, $den); $_ /= $hcf for ($num, $den); return "$num/$den"; } # Stolen from Number::Fraction. sub _hcf { my ($x, $y) = @_; ($x, $y) = ($y, $x) if $y > $x; return $x if $x == $y; while ($y) { ($x, $y) = ($y, $x % $y); } return abs($x); # changed this } __END__ 216/625 1251/1000 -1/10 -1/4
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://982023]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (6)
As of 2014-04-20 21:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (487 votes), past polls