php scientific notation significant digits - php

In the PHP manual for function sprintf I find:
e - the argument is treated as scientific notation (e.g. 1.2e+2). The
precision specifier stands for the number of digits after the decimal
point since PHP 5.2.1. In earlier versions, it was taken as number of
significant digits (one less).
Now I'm on PHP 5.4, but would like to format a number with scientific notation and indicate the number of significant digits instead of decimal places. Is there a function for this, or should I write it myself?

I looked over the (one less) part, that's all I needed.
thanks for the help!
This means that I just had to decrease the value of the precision by one to get my function to behave the way I wanted.
See here for the function I came up with tot support scientific notation using sprintf
function sn($number,$precision = 1,$case = 'e'){ //scientific notation
$precision--;
$string = str_replace('+','',sprintf('%.'.$precision.$case, $number))." ";
return $string;
}

Related

A very small exponential number in php

I have a very small exponential number and it display like:
5.2255534523412e-7
Can I display it become:
5.22e-7
Use sprintf() to format the output
http://php.net/sprintf
$a = 5.2255534523412e-7;
// change 2 to be how many decimal places you want. The e treats it as scientific notation.
echo sprintf('%.2e', $a);

PHP microtime missing digits

In PHP, when using microtime(true), I am expecting to get in most cases 6 digits to the right of the decimal.
<?php
//version 5.5.31
$time = microtime();
$timeTrue = microtime(true);
var_dump($time, $timeTrue);
// string(21) "0.64728900 1462577720"
// float(1462577720.6473)
?>
Why is the float only showing the first four digits? Sometimes I only get three digits, which makes sense. Should it not be returning float(1462577720.647289). ie 6 digits in most cases, occasionally 5 digits?
You seem to be confusing precision with digits after the decimals point.
Double precision floating points usually have a maximum precision of 14 to 16 digits and your example shows 14. Yes, all digits count. The decimal point is handled by another variable (at the floating point definition level).
The same principle would apply to very large numbers which would also lose precision after 14-15 digits long.

Trim zeros to the right of a decimal place and decimal point often

I have been handling long numbers in PHP. Like the following examples.
12.020000
12.000000
To get rid of trailing zeros and the decimal point I have been using the following inside a function.
return rtrim(rtrim($str, "0"),".");
So the above turns out like.
12.02
12
It was a bit short sighted as when 1000 gets entered it gets turned into 1.
Can someone please help me with the code to remove trailing zeros after the decimal point only?
Bonus points if the code removes the decimal place but I can always feed it into rtim($str,".").
EDIT: To be clear, I am stripping the decimal place and zeros only when displaying to the screen. Also casting to float is not an option as I also handle numbers like 0.00000001 which come out like 1.0e-9 sort of thing.
Why are you using string to hold numbers? Cast it to float and it'll solve your problem.
$string = '12.020000';
$number = (float) $string; // will be 12.02
Then, if you want to use it as string (but why?)
$string = (string) $number;
The thing that perplexes me about your question is that extra zeros won't be included in a number variable without intentionally adding them with number_format. (This may be why someone down-voted it).
Normally you don't want to use string functions (meant for text) on variables that hold numbers. If you want to round off a number, use a function like round.
http://php.net/manual/en/function.round.php
There's also number_format, which can format numbers by adding zero padding: (it doesn't actuall round, just trims off excess numbers).
http://php.net/manual/en/function.number-format.php
Since your zeros are appearing, it's likely that you simply need to multiple the variable by 1, which will essentially convert a string to a number.
Good luck!

PHP is_numeric or preg_match 0-9 validation

This isn't a big issue for me (as far as I'm aware), it's more of something that's interested me. But what is the main difference, if any, of using is_numeric over preg_match (or vice versa) to validate user input values.
Example One:
<?php
$id = $_GET['id'];
if (!preg_match('/^[0-9]*$/', $id)) {
// Error
} else {
// Continue
}
?>
Example Two:
<?php
$id = $_GET['id'];
if (!is_numeric($id)) {
// Error
} else {
// Continue
}
?>
I assume both do exactly the same but is there any specific differences which could cause problems later somehow? Is there a "best way" or something I'm not seeing which makes them different.
is_numeric() tests whether a value is a number. It doesn't necessarily have to be an integer though - it could a decimal number or a number in scientific notation.
The preg_match() example you've given only checks that a value contains the digits zero to nine; any number of them, and in any sequence.
Note that the regular expression you've given also isn't a perfect integer checker, the way you've written it. It doesn't allow for negatives; it does allow for a zero-length string (ie with no digits at all, which presumably shouldn't be valid?), and it allows the number to have any number of leading zeros, which again may not be the intended.
[EDIT]
As per your comment, a better regular expression might look like this:
/^[1-9][0-9]*$/
This forces the first digit to only be between 1 and 9, so you can't have leading zeros. It also forces it to be at least one digit long, so solves the zero-length string issue.
You're not worried about negatives, so that's not an issue.
You might want to restrict the number of digits, because as things stand, it will allow strings that are too big to be stored as integers. To restrict this, you would change the star into a length restriction like so:
/^[1-9][0-9]{0,15}$/
This would allow the string to be between 1 and 16 digits long (ie the first digit plus 0-15 further digits). Feel free to adjust the numbers in the curly braces to suit your own needs. If you want a fixed length string, then you only need to specify one number in the braces.
According to http://www.php.net/manual/en/function.is-numeric.php, is_numeric alows something like "+0123.45e6" or "0xFF". I think this not what you expect.
preg_match can be slow, and you can have something like 0000 or 0051.
I prefer using ctype_digit (works only with strings, it's ok with $_GET).
<?php
$id = $_GET['id'];
if (ctype_digit($id)) {
echo 'ok';
} else {
echo 'nok';
}
?>
is_numeric() allows any form of number. so 1, 3.14159265, 2.71828e10 are all "numeric", while your regex boils down to the equivalent of is_int()
is_numeric would accept "-0.5e+12" as a valid ID.
Not exactly the same.
From the PHP docs of is_numeric:
'42' is numeric
'1337' is numeric
'1e4' is numeric
'not numeric' is NOT numeric
'Array' is NOT numeric
'9.1' is numeric
With your regex you only check for 'basic' numeric values.
Also is_numeric() should be faster.
is_numeric checks whether it is any sort of number, while your regex checks whether it is an integer, possibly with leading 0s. For an id, stored as an integer, it is quite likely that we will want to not have leading 0s. Following Spudley's answer, we can do:
/^[1-9][0-9]*$/
However, as Spudley notes, the resulting string may be too large to be stored as a 32-bit or 64-bit integer value. The maximum value of an signed 32-bit integer is 2,147,483,647 (10 digits), and the maximum value of an signed 64-bit integer is 9,223,372,036,854,775,807 (19 digits). However, many 10 and 19 digit integers are larger than the maximum 32-bit and 64-bit integers respectively. A simple regex-only solution would be:
/^[1-9][0-9]{0-8}$/
or
/^[1-9][0-9]{0-17}$/
respectively, but these "solutions" unhappily restrict each to 9 and 19 digit integers; hardly a satisfying result. A better solution might be something like:
$expr = '/^[1-9][0-9]*$/';
if (preg_match($expr, $id) && filter_var($id, FILTER_VALIDATE_INT)) {
echo 'ok';
} else {
echo 'nok';
}
is_numeric checks more:
Finds whether the given variable is numeric. Numeric strings consist
of optional sign, any number of digits, optional decimal part and
optional exponential part. Thus +0123.45e6 is a valid numeric value.
Hexadecimal notation (0xFF) is allowed too but only without sign,
decimal and exponential part.
You can use this code for number validation:
if (!preg_match("/^[0-9]+$/i", $phone)) {
$errorMSG = 'Invalid Number!';
$error = 1;
}
If you're only checking if it's a number, is_numeric() is much much better here. It's more readable and a bit quicker than regex.
The issue with your regex here is that it won't allow decimal values, so essentially you've just written is_int() in regex. Regular expressions should only be used when there is a non-standard data format in your input; PHP has plenty of built in validation functions, even an email validator without regex.
PHP's is_numeric function allows for floats as well as integers. At the same time, the is_int function is too strict if you want to validate form data (strings only). Therefore, you had usually best use regular expressions for this.
Strictly speaking, integers are whole numbers positive and negative, and also including zero. Here is a regular expression for this:
/^0$|^[-]?[1-9][0-9]*$/
OR, if you want to allow leading zeros:
/^[-]?[0]|[1-9][0-9]$/
Note that this will allow for values such as -0000, which does not cause problems in PHP, however. (MySQL will also cast such values as 0.)
You may also want to confine the length of your integer for considerations of 32/64-bit PHP platform features and/or database compatibility. For instance, to limit the length of your integer to 9 digits (excluding the optional - sign), you could use:
/^0$|^[-]?[1-9][0-9]{0,8}$/
Meanwhile, all the values above will only restrict the values to integer,
so i use
/^[1-9][0-9\.]{0,15}$/
to allow float values too.
You can use filter_var() to check for integers in strings
<?php
$intnum = "1000022";
if (filter_var($intnum, FILTER_VALIDATE_INT) !== false){
echo $intnum.' is an int now';
}else{
echo "$intnum is not an int.";
}
// will output 1000022 is an int now

MySQL equivalent of PHP's base_convert?

Does anyone know of an equivalent function in MySQL of PHP's base_convert?
http://php.net/manual/en/function.base-convert.php
Thanks,
Mark
CONV()
you could use CONV(N,from_base,to_base)
CONV(N,from_base,to_base)
Converts numbers between different number bases. Returns a string representation of the number N, converted from base from_base to base to_base. Returns NULL if any argument is NULL. The argument N is interpreted as an integer, but may be specified as an integer or a string. The minimum base is 2 and the maximum base is 36. If from_base is a negative number, N is regarded as a signed number. Otherwise, N is treated as unsigned. CONV() works with 64-bit precision.
http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_conv

Categories