10 if (scalar @_ != 1) { return "NaN"; }
15 my ($sign, $hex) = (shift =~ /^([+\-]?)(.*)$/);
16 $hex = "0x".$hex if $hex !~ /^0x/;
21 @_ = __multiplier(@_);
22 while (scalar @_ > 1 && $_[1] =~ /^[\+\-]$/) {
23 my $operand1 = Math::BigInt->from_hex(__canonhex(shift));
25 @_ = __multiplier(@_);
26 my $operand2 = Math::BigInt->from_hex(__canonhex(shift));
27 if ($operator eq "+") {
28 $operand1->badd($operand2);
29 } elsif ($operator eq "-") {
30 $operand1->bsub($operand2);
32 die "SOMETHING WENT AWFULLY WRONG";
34 unshift @_, $operand1->as_hex();
41 while (scalar @_ > 1 && $_[1] =~ /^[\*\/%]$/) {
42 my $operand1 = Math::BigInt->from_hex(__canonhex(shift));
45 my $operand2 = Math::BigInt->from_hex(__canonhex(shift));
46 if ($operator eq "*") {
47 $operand1->bmul($operand2);
48 } elsif ($operator eq "/") {
49 $operand1->bdiv($operand2);
50 } elsif ($operator eq "%") {
51 # Here's a bit of a quirk...
52 # With OpenSSL's BN, as well as bc, the result of -10 % 3 is -1
53 # while Math::BigInt, the result is 2.
54 # The latter is mathematically more correct, but...
55 my $o1isneg = $operand1->is_neg();
57 # Math::BigInt does something different with a negative modulus,
58 # while OpenSSL's BN and bc treat it like a positive number...
60 $operand1->bmod($operand2);
61 if ($o1isneg) { $operand1->bneg(); }
63 die "SOMETHING WENT AWFULLY WRONG";
65 unshift @_, $operand1->as_hex();
72 while (scalar @_ > 1 && $_[1] eq "^") {
73 my $operand1 = Math::BigInt->from_hex(__canonhex(shift));
76 my $operand2 = Math::BigInt->from_hex(__canonhex(shift));
77 $operand1->bpow($operand2);
78 unshift @_, $operand1->as_hex();
83 # returns array ( $result, @remaining )
85 if (scalar @_ > 0 && $_[0] eq "(") {
87 my @result = __adder(@_);
88 if (scalar @_ == 0 || $_[0] ne ")") {