Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
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 (Monsignor) 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 meditating upon the Monastery: (12)
As of 2014-07-28 11:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (196 votes), past polls