Home > OS >  How can i convert integer to a float value in Perl?
How can i convert integer to a float value in Perl?

Time:10-26

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
  •  Tags:  
  • perl
  • Related