zeroclickinfo-goodies/lib/DDG/Goodie/SigFigs.pm

61 lines
1.8 KiB
Perl

package DDG::Goodie::SigFigs;
# ABSTRACT: Count the significant figures in a number.
use strict;
use DDG::Goodie;
with 'DDG::GoodieRole::NumberStyler';
triggers any => 'sigfigs', 'sig figs', 'significant';
zci answer_type => "sig_figs";
zci is_cached => 1;
sub get_sig_figs {
my $num = shift;
$num =~ s/^[-+]+//;
# Leading digits NEVER contribute towards significant figures.
$num =~ s/^0+//;
$num =~ /^(?<int_part>\d*+)(\.(?<frac_part>\d*))?$/;
my $int_part = $+{'int_part'};
my $frac_part = $+{'frac_part'};
my $sigfigs = length $int_part;
if (defined $frac_part) {
# Leading zeros after decimal point aren't significant if there
# was no integer part or the integer part consisted of only zeros.
$frac_part =~ s/^0+// if $sigfigs == 0;
return $sigfigs + length $frac_part;
};
# This isn't necessarily correct - significant figures can be
# ambiguous when not using scientific notation.
$int_part =~ s/0+$//;
return length $int_part;
}
my $number_re = number_style_regex();
handle query_raw => sub {
my $query = $_;
$query =~ s/.*?(sig(nificant)? ?(fig(ure)?|digit)s)[^,.\d]*+//i;
return if $query eq '';
$query =~ /^($number_re)\??$/ or return;
my $number_match = $1;
my $style = number_style_for($number_match);
return unless $style;
my $formatted_input = $style->for_display($number_match);
my $to_compute = $style->for_computation($number_match);
my $sigfigs = get_sig_figs $to_compute;
return unless defined $sigfigs;
return $sigfigs, structured_answer => {
data => {
title => "$sigfigs",
subtitle => "Number of Significant Figures in $formatted_input",
},
templates => {
group => 'text',
moreAt => 0,
},
};
};
1;