I have a case where some values in a data file have 64 bit wrap around which makes them very large, like, 18446744073709551608.
So I have to perform a subtraction from 2^64. I tried this using the simple
2^64 - 18446744073709551608
But I guess this number is too large and don't get the actual answer 8. What do I need to do to perform this substraction.
Check out the bignum pragma:
use bignum;
print 2**64 - 18446744073709551608;
This should properly print 8.
Note that bignum is just a layer that makes all constant numbers automatically Math::BigFloat or Math::BigInt objects. If you only want this for some numbers, you can either specify the use bignum; in a restricted scope, add no bignum; in places, or explicitly use Math::BigFloat->new('your constant') (or BigInt) to make particular numbers and the results of any operations involving them big.
use bignum ;
print 2**64 - 18446744073709551608 ,"\n" ;
in perl language , ^ = ** , mod = %
good luck !
Related
I need to convert the following integers numbers
29900
17940
1
in to decimal format like
299.00
179.40
0.01
I tried already Data/Types.pm but
to_decimal(1, 2)
return 1.00
Perl does not have data types in the sense of integer, float or string. All you need to do is divide by 100. If you want an output with two decimals, use sprintf to format it.
printf '%.02d', 29900 / 100;
Will output 299.00. Note that printf is like sprintf, but with printing instead of returning.
You can read perldata to learn more about what kinds of data Perl has.
Under the hood at the XS and C layer, there are of course data types. You can learn about them in perlguts. But the whole point of a higher language is to abstract those things away. So if all you do is write Perl code, you never need to care that those exist or how they work.
Are there any system functions that support more than 32 bits in System Verilog? I want to convert a real-valued quantity to an integral value that contains more than 32 bits. The $rtoi() system function does precisely what I want for values that can be represented in 32 bits or less. Is there a built-in for this, or would I need to write my own?
For a concrete example, I would like to be able to do something like the following:
logic [41:0] test_value;
initial begin
test_value = $rtoi($pow(2.0, 39.5));
end
Where, instead of $rtoi(), I would use the unknown sought after system function. Given the correct function, I would expect this to result in test_value being initialized with the bit sequence 42'b1011010100000100111100110011001111111001 or possibly 42'b1011010100000100111100110011001111111010 if rounding is supported.
I can write my own function, but I would like to avoid reinventing the wheel unless there is no wheel.
A implicit cast from real to integral gives you what you want with rounding
test_value = 2.0**39.5;
Or you can use an explicit cast
typedef logic [41:0] uint42_t;
test_value = uint42_t'(2.0**39.5);
I need to read some numbers in a database and write them into a text file using Perl.
In the table where are the numbers, the data format is defined as numeric (25,5) (it reads 25 digits, including 5 decimals).
I format the numbers in my file with a sprintf "%.5f", $myvalue to force 5 decimals and I just noticed that for greats values, there is a precision loss for numbers with more than 17 digits :
db = 123.12345
file = 123.12345 (OK)
db = 12345678901234891.12345
file = 12345678901234892.00000 (seems to be rounded to upper integer)
db = 12345678901234567890.12345
file = 12345678901234567000.00000 (truncation ?)
What is Perl's greatest precision for fixed decimal numbers?
I am aware of the concepts and limitations of floating point arithmetic in general, but I am not a Perl monk and I do not know the internals of Perl so I don't know if it is normal (or if it is related at all to floating point). I am not sure either if it is a internal limitation of Perl, or a problem related to the sprintf processing.
Is there a workaround or a dedicated module that could help with that problem?
Some notable points :
this is an additional feature of a system that already uses Perl, so using another tool is not an option
the data being crunched is financial so I need to keep every cent and I cannot cope with a +/- 10 000 units precision :^S
Once again, I am finding a solution right after asking SO. I am putting my solution here, to help a future visitor :
replace
$myout = sprintf "%.5f", $myvalue;
by
use Math::BigFloat;
$myout = Math::BigFloat->new($myvalue)->ffround( -5 )->bstr;
Without modules like Math::BigFloat, everything above 16 digits is pure magic... e.g.
perl -e 'printf "*10^%02d: %-.50g\n", $_, log(42)*(10**$_) for (0..20)'
produces
*10^00: 3.7376696182833684112267746968427672982215881347656
*10^01: 37.376696182833683224089327268302440643310546875
*10^02: 373.76696182833683224089327268302440643310546875
*10^03: 3737.6696182833684360957704484462738037109375
*10^04: 37376.6961828336861799471080303192138671875
*10^05: 373766.96182833681814372539520263671875
*10^06: 3737669.6182833681814372539520263671875
*10^07: 37376696.18283368647098541259765625
*10^08: 373766961.82833683490753173828125
*10^09: 3737669618.283368587493896484375
*10^10: 37376696182.83368682861328125
*10^11: 373766961828.33685302734375
*10^12: 3737669618283.36865234375
*10^13: 37376696182833.6875
*10^14: 373766961828336.8125
*10^15: 3737669618283368.5
*10^16: 37376696182833688
*10^17: 373766961828336832
*10^18: 3737669618283368448
*10^19: 37376696182833684480
*10^20: 373766961828336828416
What is Perl's greatest precision for fixed decimal numbers?
Perl doesn't have fixed point decimal numbers. Very few languages do, actually. You could use a module like Math::FixedPoint, though
Perl is storing your values as floating-point numbers internally.1 The precision is dependent on how your version of Perl is compiled, but it's probably a 64-bit double.
C:\>perl -MConfig -E "say $Config::Config{doublesize}"
8
A 64-bit double-precision float2 has a 53-bit significand (a.k.a. fraction or mantissa) which gives it approximately 16 decimal characters of precision. Your database is defined as storing 25 characters of precision. You'll be fine if you treat the data as a string but if you treat it as a number you'll lose precision.
Perl's bignum pragma provides transparent support for arbitrarily large numbers. It can slow things down considerably so limit its use to the smallest possible scope. If you want big floats only (without making other numeric types "big") use Math::BigFloat instead.
1. Internally, perl uses a datatype called an SV that can hold floats, ints, and/or strings simultaneously.
2. Assuming IEEE 754 format.
Alternatively, if you're just transferring the values from the database to a text file and not operating on them as numbers, then have the DB format them as strings. Then read and print them as strings (perhaps using "printf '%s'"). For example:
select Big_fixed_point_col(format '-Z(24)9.9(5)')(CHAR(32))
Recently, I came across the following piece of code in perl that returns the minimum numeric value among all passed arguments.
return 0 + ( sort { $a <=> $b } grep { $_ == $_ } #_ )[0];
I usually use simple linear search to find the min/max in a list, which for me seems to be simple and adequately optimal. Is the above code in any way better than simple linear search? Anything to do with perl in this case? Thanks!
O() doesn't say anything about how long an algorithm takes. For example, all else being equal, I'd always choose Algorithm 2 among the following two:
Algorithm 1: O(2*N + 1000 days) = O(N)
Algorithm 2: O(5*N + 100 ms) = O(N log N)
O() specifies how the time the algorihm takes scales as the size of the input increases. (Well, it can be used for any resources, not just time.) Since the earlier two answers only talk in terms of O(), they are useless.
If you want to know how fast an algorithm which algorithm is better for an input of a given size, you'll need to benchmark them.
In this case, it looks like List::Util's min is always significantly better.
$ perl x.pl 10
Rate sort LUmin
sort 1438165/s -- -72%
LUmin 5210584/s 262% --
$ perl x.pl 100
Rate sort LUmin
sort 129073/s -- -91%
LUmin 1485473/s 1051% --
$ perl x.pl 1000
Rate sort LUmin
sort 6382/s -- -97%
LUmin 199698/s 3029% --
Code:
use strict;
use warnings;
use Benchmark qw( cmpthese );
use List::Util qw( min );
my %tests = (
'sort' => 'my $x = ( sort { $a <=> $b } #n )[0];',
'LUmin' => 'my $x = min #n;',
);
$_ = 'use strict; use warnings; our #n; ' . $_
for values %tests;
local our #n = map rand, 1..( $ARGV[0] // 10 );
cmpthese(-3, \%tests);
You are right. If you do not need sorted data for any other purpose, the simple linear search is fastest. To do its job, a sort would have to look at each datum at least once, anyway.
Only when the sorted data would be useful for other purposes -- or when I didn't care about run time, power usage, heat dissipation, etc. -- would I sort data to find the minimum and maximum values.
Now, #SimeonVisser is correct. The sort does have O(n*log(n)). This is not as much slower than O(n) as many programmers imagine that it were. In practical cases of interest, the overhead of managing the sort's balanced binary tree (or other such structure) probably matters about as much as the log(n) factor does. So, one needn't shrink in horror from the prospect of sorting! However, the linear search is still faster: you are quite right about this.
Moreover, #DavidO adds such an insightful comment that I would quote it here in his own words:
A linear search is also an easier algorithm to generalize. A linear search could easily (and relatively efficiently) be disk based for large data sets, for example. Whereas doing a disk based sort becomes relatively expensive, and even more complex if the field sizes aren't
normalized.
Linear search is O(n) for obvious reasons. Sorting is O(n log n) (see sort in Perl documentation). So yes, linear search is indeed faster in terms of complexity. This does not only apply to Perl but to any programming language that implements these algorithms.
As with many problems, there are multiple ways to solve it and there are also multiple ways to obtain the min/max of a list. Conceptually I would say that linear search is better when you only want the min or max of a list as the problem does not call for sorting.
I have a program in Perl that works with probabilities that can occasionally be very small. Because of rounding error, sometimes one of the probabilities comes out to be zero. I'd like to do a check for the following:
use constant TINY_FLOAT => 1e-200;
my $prob = calculate_prob();
if ( $prob == 0 ) {
$prob = TINY_FLOAT;
}
This works fine, but I actually see Perl producing numbers that are smaller than 1e-200 (I just saw a 8.14e-314 fly by). For my application I can change calculate_prob() so that it returns the maximum of TINY_FLOAT and the actual probability, but this made me curious about how floating point numbers are handled in Perl.
What's the smallest positive floating-point value in Perl? Is it platform-dependent? If so, is there a quick program that I can use to figure it out on my machine?
According to perldoc perlnumber, Perl uses the native floating point format where native is defined as whatever the C compiler that was used to compile it used. If you are more worried about precision/accuracy than speed, take a look at bignum.
The other answers are good. Here is how to find out the approximate ε if you did not know any of that information and could not post your question on SO ;-)
#!/usr/bin/perl
use strict;
use warnings;
use constant MAX_COUNT => 2000;
my ($x, $c);
for (my $y = 1; $y; $y /= 2) {
$x = $y;
# guard against too many iterations
last if ++$c > MAX_COUNT;
}
printf "%d : %.20g\n", $c, $x;
Output:
C:\Temp> thj
1075 : 4.9406564584124654e-324
It may be important to note that that smallest number is what's called a subnormal number, and math done on it may produce surprising results:
$ perl -wle'$x = 4.94e-324; print for $x, $x*1.4, $x*.6'
4.94065645841247e-324
4.94065645841247e-324
4.94065645841247e-324
That's because it uses the smallest allowed (base-2) exponent and a mantissa of the form (base-2) 0.0000000...0001. Larger, but still subnormal, numbers will also have a mantissa beginning 0. and an increasing range of precision.
I actually don't know how perl represents floating point numbers (and I think this is something you configure when you build perl), but if we assume that IEEE 754 is used then epsilon for a 64 bit floating point number is 4.94065645841247E-324.