Re: Identify if a scalar is int, double or text



On May 11, 11:07 pm, anno4...@xxxxxxxxxxxxxxxxxxxxxx wrote:
Klaus <klau...@xxxxxxxxx> wrote in comp.lang.perl.misc:

On May 11, 2:49 pm, anno4...@xxxxxxxxxxxxxxxxxxxxxx wrote:

Klaus <klau...@xxxxxxxxx> wrote in comp.lang.perl.misc:
I have a list of 4 scalars
my @L = (3, '3', 3.0, '3.0');
I want to write a subroutine type_id which returns either 'int',
'double', 'text' (or '?') for each of the scalars
I have found a solution where I use Devel::Peek, call Dump(), redirect
STDERR into an "in-memory" file ( \$data ) and analyse the "in-memory"
content:

[snip]

The B::* set of modules should have the means to get the info
without catching printed output.

That's it - it's the B module which I was looking for (I knew it
existed, but I never thought I would ever use it).

Thanks a million !!

Glad I could help, but I'm asking myself why you need to
know these differences. Perl works very hard to let us deal with
integers, floats, strings and references in a unified way. In
particular, the difference of a float and an int is usually
irrelevant. If it matters to your program, you are probably
not doing something the Perl way.

I agree with that.

But I have a case where I need more control over the way Perl manages
numerical values.

At one point in the future, I will certainly have to read "perldoc
perlxstut" to gain understanding of how I can use C to control
numerical values, but being on Windows XP / Activestate Perl 5.8.8
with next to no background in C, I thought I tackle the problem first
with whatever tool / module / function Perl is giving me.

Here is my case:

I have written a Perl program where some of the variables have a
special requirement, that is they deal exclusively with monetary Euro
values (i.e. the requirement is that calculations happens in normal
IEEE float/double arithmetic, and assignment to any special "monetary"
variable must be rounded to the 2nd decimal).

My first approach was to use sprintf("%.2f", $var) whenever I assign
values to a "monetary Euro" variable, but this falls foul of the way
numerical values are stored internally (i.e. 0.10 can not be
represented as an exact double).

I worked around that by storing integer "cents" rather than "Euros": I
use sprintf("%.0f", $var) when I assign "monetary" values.

That works fine, but I found out that a "monetary" value above 20
million Euros ( > 2^31 cents ) is not stored as an integer, but as a
double. As I said, it seems to work and the double seems to stick to
its "integer" properties, but I want to monitor very closely what
happens with that "double" if I grow bigger and bigger values.

My final solution would be to tie variables to some C-subroutines that
(efficiently) do 4 things when I assign values to that variable:

1. Round values to the nearest integer (same as sprintf "%.0f", but
more efficient).
2. If that value fits into an int (i.e. -2^31 <= val <= 2^31-1), then
it must always be stored as an int.
3. If it is stored as a double, then make sure that double has no
decimal.
4. If a value is too big to be represented as a double with no
decimals, then
4a.) either set the variable to the maximum integral "double"
value,
4b.) or, depending on a compile time option, die.

-- Klaus



Anno


.