Re: Coping with decimals
by Zaxo (Archbishop) on Jun 02, 2005 at 09:34 UTC
|
my $calc = ($X-$Y)/$Z;
my $phase = $calc - int $calc;
| [reply] [d/l] |
|
|
Be careful with this technique as storage of decimals in a computer is never accurate and a conversion to int could throw you off.
See this node for a discussion on the same lines
Dividing and format
Specifically the links in my reply here:
Ninthwave's reply in Dividing and format
"No matter where you go, there you are." BB
| [reply] |
|
|
Be also careful if you have negative numbers...
e.g. $X = 1, $Y = 7, $Z = 5
Then:
($X-$Y) = -6, so $calc = ($X-$Y)/$Z = -1.2
but $phase = $calc - int $calc = -1.2 -1 = -2.2, which is not what you wanted...
--------------------------------
An idea is not responsible for the people who believe in it...
| [reply] |
|
|
$ perl -e'my ($X,$Y,$Z)=(1,7,5);my $c=($X-$Y)/$Z;print $c-int$c, $/'
-0.2
$
That may not be what's wanted, either.
| [reply] [d/l] |
|
|
| [reply] |
Re: Coping with decimals
by BrowserUk (Patriarch) on Jun 02, 2005 at 09:43 UTC
|
#! perl -slw
use strict;
use POSIX qw[ modf ];
my $float = 2.543;
my( $fract, $integral ) = modf( $float );
print "$integral - $fract";
__END__
P:\test>462825
2 - 0.543
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
| [reply] [d/l] |
Re: Coping with decimals
by Corion (Patriarch) on Jun 02, 2005 at 09:30 UTC
|
What have you tried already?
While Perl is a programming language with many special features, it still has the feature set that you can expect from other programming languages. Even if you don't know how to express this in Perl syntax, you should still be able to come up with a set of instructions that does what you want.
For example, the following set of instructions does what you want and should be easily implemented in Perl:
- If the absolute of the number x is smaller than 1.0, return the number
- If the number x is larger than 1, return the phase of the number x-1
- If the number x is smaller than -1, return the phase of the number x+1
It's easy to convince yourself that this will always produce a solution.
| [reply] |
Re: Coping with decimals
by tlm (Prior) on Jun 02, 2005 at 13:36 UTC
|
Given that you're dealing with phases, presumably with period 1, if your calculation can produce negative numbers, then I would recommend:
$x - POSIX::floor( $x );
instead of
$x - int( $x );
or
( POSIX::modf( $x ) )[ 0 ];
| [reply] [d/l] [select] |
Re: Coping with decimals
by holli (Abbot) on Jun 02, 2005 at 09:37 UTC
|
several ways come to my mind.
my $phase;
my $number = 2.543;
#substr
$phase = "0" . substr($number,index($number,"."));
#regex
$number =~ /(\..+)/;
$phase = "0$1";
#int
$phase = $number-int($number);
| [reply] [d/l] |
|
|
If the number doesn't contain a decimal part, you could end up using $1 from a previous match. I'd suggest (maybe some parenthesis can be avoided, but I'm not able to test ATM):
$phase = '0' . (($number =~ /(\..+)/) ? $1 : '');
I found particularly wit to include the "." inside $1, in order to avoid repetition.
Flavio (perl -e 'print(scalar(reverse("\nti.xittelop\@oivalf")))')
Don't fool yourself.
| [reply] [d/l] [select] |
|
|
| [reply] |
|
|
The standard Perl approach to rounding numbers (with sprintf) amounts to using a string manipulation for what is arguably an arithmetic task. Did you have any particular error in mind?
When I first saw the question, the two solutions I thought of were $x - int( $x ) or indeed something along the lines of $x =~ s/\d+(?=\.)//, and I'm curious about what errors could have resulted from the latter approach.
| [reply] [d/l] |
|
|
|
|
|
|