units script produces incorrect results for definitions that include a fractional factor
Closed this issue · 1 comments
The units script incorrectly handles fractional multipliers in both entry and in definitions. For example, the documentation (in the DESCRIPTION section) offers this usage example:
You have: 1|2 inch
You want: cm
* 1.27
/ 0.78740157
Those numbers are correct. However, the actual output when you enter this example is:
You have: 1|2 inch
You want: cm
* 0.635
/ 1.5748
Note that the values are squares of the correct values. Upon investigation I discovered that the lex subroutine is capturing fractions twice, causing the fraction to be multiplied by itself during reduction. This problem also occurs when the definition includes a fraction, not just on entry of a fractional unit. For example, the conversion from year to month (where month is defined in the DATA section as "1|12 year") yields this result:
You have: month
You want: year
* 0.00694444
/ 144
The problem traces to this bit of code in the lex subroutine:
my $N = '(?:\d+\.\d+|\d+|\.\d+)(?:[eE][-+]?\d+)?';
my @t = split /(
(?: \*.\* | !.! ) # Special 'new unit' symbol
| [()*-] # Symbol
| \s*(?:\/|\bper\b)\s* # Division
| ($N\|$N) # Fraction
| $N # Decimal number
| \d+ # Integer
| [A-Za-z_][A-Za-z_.]* # identifier
| \s+ # White space
)/ox, $s;
Note that the $N regex includes ?: to disable group capturing. However, this does not carry through to the Fraction alternative within the split pattern. Changing the subpattern to (?:$N|$N) seems to completely resolve the issue.
I will attempt to clone the repo, fix this bug, and then push the fix.
Thanks for looking into this.