| Locale-MakePhrase documentation | Contained in the Locale-MakePhrase distribution. |
Locale::MakePhrase::Numeric - Numeric translation/stringification
This module provides the functionality to translate and/or stringify a numeric, into something suitable for the string being translated.
The following class-functions are provided:
This class-function implements the stringification of a number to a suitable output format. The $options parameter is used to control the formatting behaviour:
numeric_formatThe formatting appled to the number; this must be an array reference containing 4 elements:
decimal seperator
thousand's seperator
when the value is negative, the symbol shown to the left of the number
when the value is negative, the symbol shown to the right of the number
widthSet the number of characters used in the output.
precisionSet the maximum number of decimal places processed.
fixedSet this to true to make the output use a fixed number of decimal
places, irrespective if the values are all zeros. Use this in
conjunction with the precision setting.
scientificSet this value to true to make the number show exponential notation.
leading_zerosSet this to true to make the output display zeros; combine this
with the width setting.
If the number is purely an integer, you have not set the fixed or
scientific settings, we try to keep the number from turning into
its scientific notation (ie: we try to stop big numbers turning into
something like 1.04E+09).
| Locale-MakePhrase documentation | Contained in the Locale-MakePhrase distribution. |
package Locale::MakePhrase::Numeric; our $VERSION = 0.1; our $DEBUG = 0;
use strict; use warnings; use base qw(Exporter); use Data::Dumper; use vars qw(@EXPORT_OK); @EXPORT_OK = qw( stringify); local $Data::Dumper::Indent = 1 if $DEBUG; # Common formatting types sub DOT { return [ '.','' ,'-','' ]; } sub COMMA { return [ ',','' ,'-','' ]; } sub DOT_COMMA { return [ '.',',','-','' ]; } sub COMMA_DOT { return [ ',','.','-','' ]; } #--------------------------------------------------------------------------
sub stringify { shift if (@_ == 3); my ($number,$options) = @_; my $format = $options->{numeric_format}; $format = DOT unless $format; print STDERR "Stringify format: '".join("' '",@$format)."'\n" if $DEBUG > 3; my $negative = $number < 0 ? 1 : 0; $number = abs($number); # Don't let the %G of sprintf, turn ten million (or bigger) into something like 1E+007 # Otherwise, try to apply various formatting options. if (!$options->{fixed} and !$options->{scientific} and $number < 10_000_000_000 and $number == int($number)) { $number += 0; # Just use normal integer stringification. } else { my $mode = "%"; $mode .= $options->{width} if (exists $options->{width}); if (exists $options->{precision}) { $mode .= ".".$options->{precision}; } else { $mode .= ".15"; } if ($options->{fixed}) { $mode .= "F"; } else { $mode .= "G"; } $number = CORE::sprintf($mode,$number); if(!$options->{fixed} and !$options->{scientific} and $number < 10_000_000_000 and $number == int($number)) { $number += 0; # Just use normal integer stringification. } } # We optionally apply numeric formatting (eg: put comma's into big numbers) if ($format) { # has the format defined a seperator, we add them if ($format->[1]) { # The initial \d+ gobbles as many digits as it can, and then we # backtrack so it un-eats the rightmost three, and then we # insert the comma there. while( $number =~ s/^(\d+)(\d{3})/$1_$2/s ) {1} my $t = $format->[0]; if ($t eq '_') { $number =~ s/_/#/g; $number =~ s/\./_/; $t = $format->[1]; $number =~ s/#/$t/g; } else { $number =~ s/\./$t/; $t = $format->[1]; $number =~ s/_/$t/g; } } else { my $t = $format->[0]; $number =~ s/\./$t/ if ($t ne '.'); } } # do we want leading zero's $number = tr< ><0> if ($options->{leading_zeros}); # apply negative-formatting $number = $format->[2].$number.$format->[3] if $negative; return $number; } 1; __END__ #--------------------------------------------------------------------------