force IV to NV

M

Martin Mohr

Hello,

to work around a problem I'm having with SDL::OpenGL (see earlier
thread), I'd like to know a way to force an integer value (IV) to become
a double value (NV). It's not as easy as I first thought:

perl -MDevel::peek -e "$a = 1;$a+=0.0; Dump $a"

This shows that $a remains IV. How can I achive this cast?

Ciao
Martin
 
A

attn.steven.kuo

I suspect that is due to 0.0 having an exact
binary representation. You can try another
operand for addition -- one that doesn't
have an exact binary represenation:


Bah -- let me retract that. I should
have said that 0.0 is more simply
represented as an integer and
perl somehow uses an integer there
instead of a floating point number. Whether a floating
point number has an exact binary
representation or not has nothing to do with
it as I get the same results with:

$ perl -MDevel::peek -le '$z = 1; $z + 0.5 - 0.5; Dump $z;'
SV = PVNV(0x1803880) at 0x1800f70
REFCNT = 1
FLAGS = (IOK,NOK,pIOK,pNOK)
IV = 1
NV = 1
PV = 0
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Abigail
There's no need to change an IV to an NV when adding two integers.
But there is on division:


$ perl -MDevel::peek -e '$a = 1;$a/=1; Dump $a'
SV = PVNV(0x8182828) at 0x817fed4
REFCNT = 1
FLAGS = (NOK,pNOK)
IV = 1
NV = 1
PV = 0

a) There is no need to mutilate $a:
perl -MDevel::peek -we "$a = 1;(undef)=$a*1.5; Dump $a"
SV = PVNV(0x74c7c) at 0x589b8
REFCNT = 1
FLAGS = (IOK,NOK,pIOK,pNOK)
IV = 1
NV = 1
PV = 0

b) If one really NEEDS a particular field of a scalar to be present,
one uses some seriously broken Perl module.

Hope this help,
Ilya
 
M

Martin Mohr

Ilya said:
b) If one really NEEDS a particular field of a scalar to be present,
one uses some seriously broken Perl module.

Thanks everybody for the answers. I am afraid you are right. The XS of
SDL::OpenGL does, for example in glMultMatrix,

mat = (i < items && SvNOK(ST(i)) ? SvNV(ST(i)) : 0.0 );

So it checks SvNOK before using SvNV. This causes problems when a
parameter hasn't been in touch with floating point stuff before usage.
What makes this even worse, is that scalars can also lose their floating
point property again.

So as a workaround one can bring all parameters in contact with floating
point operations (as you have shown) before passing them to
glMultMatrix. Or one uses another module. Like yours for example.

Ciao
Martin
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Martin Mohr
Ilya said:
b) If one really NEEDS a particular field of a scalar to be present,
one uses some seriously broken Perl module.

Thanks everybody for the answers. I am afraid you are right. The XS of
SDL::OpenGL does, for example in glMultMatrix,

mat = (i < items && SvNOK(ST(i)) ? SvNV(ST(i)) : 0.0 );


Your analysis looks correct: this is a seriously wrong piece of code.
The only purpose I could think for writing something as horrible as
this is to avoid "undefined value used in..." warning; but then one
must have used SvOK(), not SvNOK.
So it checks SvNOK before using SvNV.

For those less familiar with what Perl macros do: SvNV() is designed
to cover all the bases (but will emit the warning on undef if warnings
are enabled). Any homegrown modification of SvNV() (like the
conditional above) will break something...
This causes problems when a
parameter hasn't been in touch with floating point stuff before usage.
What makes this even worse, is that scalars can also lose their floating
point property again.

Do not think I know what you are talking about in the latter sentence.
So as a workaround one can bring all parameters in contact with floating
point operations (as you have shown) before passing them to
glMultMatrix. Or one uses another module. Like yours for example.

Sorry, I have little time to work on it lately. Moreover, itis not
"my module". I'm just the latest of maintainers - I wrote very little
of it.

Yours,
Ilya

P.S. One solution is to run over this with a smart search-and-replace
pattern in an editor...
 
X

xhoster

Martin Mohr said:
Ilya said:
b) If one really NEEDS a particular field of a scalar to be present,
one uses some seriously broken Perl module.

Thanks everybody for the answers. I am afraid you are right. The XS of
SDL::OpenGL does, for example in glMultMatrix,

mat = (i < items && SvNOK(ST(i)) ? SvNV(ST(i)) : 0.0 );

So it checks SvNOK before using SvNV. This causes problems when a
parameter hasn't been in touch with floating point stuff before usage.
What makes this even worse, is that scalars can also lose their floating
point property again.


Perlguts seeems to be wrong. It says:

What's Really Stored in an SV?

Recall that the usual method of determining the type of scalar you
have is to use "Sv*OK" macros. Because a scalar can be both a
number and a string, usually these macros will always return TRUE
and calling the "Sv*V" macros will do the appropriate conversion of
string to inte- ger/double or integer/double to string.

I figured that the "usually..always" means SvNOK will always return true
for non-tied, non-magical variables. But obviously it doesn't mean that.
I throught SvNOK means "Is it OK to call SvNV and trust what it gives?" but
apparently that is not what it means.

Xho
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top