I searched for a built in function to convert an integer to float type, but there isn't any. I want to convert a number 1000 into 1000.0
CodePudding user response:
For actual maths, there is no need to convert numbers. Perl doesn't make a distinction between integers and floats (it actually does under the hood, but that isn't relevant).
If you want to output a number with decimals, you can use sprintf
or printf
respectively.
The %f
conversion is what you want here. You can tell it to have decimals after the comma.
printf '%.1f', 1000; # will print 1000.0
This will respect your locale and use the correct sign for the comma.
CodePudding user response:
If you're actually asking how to convert a float into a decimal string representation with decimal places, then you can use printf
/sprintf
.
For example, the following prints $x
with one decimal place, whether it's a number stored as an integer or float.
my $x = 1000;
printf "%.1f", $x; # 1000.0
But to answer your question, there is no builtin function to convert an integer to a float.
Perl will automatically convert a scalar to a floating point number when needed, so there's normally no need for something this.
While 1.0
creates a float (NOK
), you can't even get one by multiplying by 1.0
(using * 0.1
or *= 0.1
).
$ perl -MDevel::Peek -e'
my $x = 1000; Dump( $x );
my $y = 1.0; Dump( $y );
my $z = $x * $y; Dump( $z );
'
SV = IV(0x55efe5c37e58) at 0x55efe5c37e68
REFCNT = 1
FLAGS = (IOK,pIOK) <-- Signed integer
IV = 1000
SV = NV(0x55efe5c37e98) at 0x55efe5c37eb0
REFCNT = 1
FLAGS = (NOK,pNOK) <-- Floating point number
NV = 1
SV = IV(0x55efe5c37ff0) at 0x55efe5c38000
REFCNT = 1
FLAGS = (IOK,pIOK) <-- Signed integer
IV = 1000
It's simply not something you should want to do.
The issue is that some interfaces impart meaning on how a number is stored. For example, a JSON serializer might serialize numbers stored as integers differently than numbers stored as floats. This could be considered a bug.
Bug or not, it doesn't change the fact that you need the requested conversion. It can be done using the Perl API.
use Inline C => <<'__EOS__';
SV* SvNV_force( SV* sv ) {
SvREFCNT_inc( sv );
sv_setnv( sv, SvNV( sv ) );
return sv;
}
__EOS__
use Devel::Peek qw( Dump );
my $x = 1000; Dump( $x );
SvNV_force( $x ); Dump( $x );
SV = IV(0x55a354e92508) at 0x55a354e92518
REFCNT = 1
FLAGS = (IOK,pIOK) <-- Signed integer
IV = 1000
SV = PVNV(0x55a354e611a0) at 0x55a354e92518
REFCNT = 1
FLAGS = (NOK,pNOK) <-- Floating point number
IV = 1000
NV = 1000
PV = 0