I have a loop that calculates a couple revenue values then adds them together, like this:
$SalesGrowth = $C2012Sales+$C2011Sales;
In some cases, this works, and I get the expected, e.g.: 761.9 + 759.0 = 1520.9
In others, it looks like PHP randomly decides to round incorrectly (??) AND change the units (??) and I get:
8,788.0 + 8,794.3 = 16
What is going on here? I've even tried echoing out the separate sales values separated by a space, and they show up correctly, so the underlying figures aren't wrong.
Interpreted as a number, 8,788.0 is just 8, and parsing stops at the comma.
You'll need some locale-aware number parsing if you want to allow gimmicks like thousands-separators.
Update: If you have the Zend Framework, you can do this:
require_once('Zend/Locale/Format.php');
$locale = new Zend_Locale('en_GB'); // #1
$v = "8,410.5";
$n = Zend_Locale_Format::getNumber($v, array('locale' => $locale,'precision' => 3));
echo 2 * $number; // prints "16821"
Instead of hard-coding the locale, you could try and take it from the environment: new Zend_Locale(setlocale(LC_ALL, ""))
Dude the comma issue....
remove all the commas from the numbers before adding them...
str_replace(",","",$no1);
This is pretty simple... When you ask PHP to use the + operator, it will implicitly convert these strings such as "8,788.0" to an numeric value. Since you have a , character, it terminates the usefulness of the number, and it results in it being interpreted as 8. And so on...
Get rid of the non [0-9.] characters and it will work better.
Notice that 761.9 is a valid number, while 8,788.0 is not (from PHP's point of view).
So 8,788.0 in number context will evaluate as 8, just like 8,794.3. And 8+8 = 16.
To fix this problem, process your data to make numbers formatted properly.
Related
In PHP I have the following code:
<?PHP
$var = .000021;
echo $var;
?>
the output is 2.1E-5 !
Why? it should print .000021
Use number_format() to get what you're after:
print number_format($var, 5);
Also check sprintf()
2.1E-5 is the same number as 0.000021. That's how it prints numbers below 0.001. Use printf() if you want it in a particular format.
Edit If you're not familiar with the 2.1E-5 syntax, you should know it is shorthand for 2.1×10-5. It is how most programming languages represent numbers in scientific notation.
Use number_format or sprintf if you want to see the number as you expect.
echo sprintf('%f', $var);
echo number_format($var, 6);
To show a number up to 8 decimal spaces, without extra zeroes to the right (as number_format does, which can be annoying), use this:
echo rtrim(rtrim(sprintf('%.8F', $var), '0'), ".");
In general, a number is a number, not a string, and this means that any programming language treats a number as a number. Thus, the number by itself doesn't imply any specific format (like using .000021 instead of 2.1e-5). This is nothing different to displaying a number with leading zeros (like 0.000021) or aligning lists of numbers. This is a general issue you'll find in any programming language: if you want a specific format you need to specify it, using the format functions of your programming language.
Unless you specify the number as string and convert it to a real number when needed, of course. Some languages can do this implicitly.
The previous answers responded to OP question, but none offered the code to do it.
Use this function to format any number with E- format.
function format_amount_with_no_e($amount) {
$amount = (string)$amount; // cast the number in string
$pos = stripos($amount, 'E-'); // get the E- position
$there_is_e = $pos !== false; // E- is found
if ($there_is_e) {
$decimals = intval(substr($amount, $pos + 2, strlen($amount))); // extract the decimals
$amount = number_format($amount, $decimals, '.', ','); // format the number without E-
}
return $amount;
}
Please note the function will always return a string.
Programming languages have different methods for storing numbers in memory. This is determined by the type of number that is being used. In your case, you have a floating point number (a fraction) that is to large to be stored as a fixed point number ( fractions are stored in this manner depending on their size).
This is a very important feature especially when working with very large or very small numbers. For instance, NASA or spaceX uses special storage methods for its calculations to ensure that the rockets the re-enter earths orbit land where they should.
Also, different storage methods take up different amounts of memory. However, the solution provided above should work. Just remember round off errors might occur with very big or small numbers.
I am trying to make this calculation in php but is giving me wrong result. I think that is right.
And if i do 5000.00 - 100.10 it works, but i want the 5,000.00 to work too.
This is my code:
To create the 5,000.00 i have used number_format(5000, 2).
Aswell to the 100.10
$total = $value1 - $value2;
echo $total;
?>
$total = -95.00
I am trying to make this calculation in php but is giving me wrong result. I think that is right.
And if i do 5000.00 - 100.10 it works, but i want the 5,000.00 to work too.
Please Help...
If you want to do arithmetic on number, you can't have the thousands separator (,). What's happening is 5,000.00 is being read as 5 (it stops interpreting it as a number as soon as it hits the comma) and then you're getting 5 - 100.10 which is -95.10 (I'm thinking you left off the .10 in your example.
You'll need to convert first:
$value1 = floatval(str_replace(',', '', $original_value1))
$value2 = floatval(str_replace(',', '', $original_value2))
I'm assuming here that you have them as strings originally. These remove the comma separator.
It sounds like you're confusing rendering in the UI with calculations.
It's perfectly reasonable for a user to see currencies rendered according to their locale rules (e.g. a String "$1,000.00" in USA), but the calculations in the back need to done on a floating point number (e.g. 1000.0).
So you have to be able to convert back and forth between them. You can't make arithmetic operations work on a String. Better to parse the String to a float, do the operations, then convert that back to String for rendering.
I want to build a chessboard via bitboard system.
Starting with 12 bitboards i want to display a table (chessboard), during loop/iteration a piece must be drawn.
How do i loop through all bitvalues?
I was thinking of something like:
for(i=0;i<64;i++)
draw table / build array / draw empty square
These are my my values to start a game:
function init_game($whitePlayer,$blackPlayer)
{
$WhitePawns = '0000000000000000000000000000000000000000000000001111111100000000';
$WhiteKnights = '0000000000000000000000000000000000000000000000000000000001000010';
$WhiteBishops = '0000000000000000000000000000000000000000000000000000000000100100';
$WhiteRooks = '0000000000000000000000000000000000000000000000000000000010000001';
$WhiteQueens = '0000000000000000000000000000000000000000000000000000000000010000';
$WhiteKing = '0000000000000000000000000000000000000000000000000000000000001000';
$BlackPawns = '0000000011111111000000000000000000000000000000000000000000000000';
$BlackKnights = '0100001000000000000000000000000000000000000000000000000001000010';
$BlackBishops = '0010010000000000000000000000000000000000000000000000000000100100';
$BlackRooks = '1000000100000000000000000000000000000000000000000000000000000000';
$BlackQueens = '0000100000000000000000000000000000000000000000000000000000000000';
$BlackKing = '0001000000000000000000000000000000000000000000000000000000000000';
$WhitePieces = $WhitePawns|$WhiteKnights|$WhiteBishops|$WhiteRooks|$WhiteQueens|$WhiteKing;
$BlackPieces = $BlackPawns|$BlackKnights|$BlackBishops|$BlackRooks|$BlackQueens|$BlackKing;
}
Some people asked me: why bitboard appoach?
Answer:
About bitboard
A bitboard, often used for boardgames such as chess, checkers and othello, is a specialization of the bitset data structure, where each bit represents a game position or state, designed for optimization of speed and/or memory or disk use in mass calculations. Bits in the same bitboard relate to each other in the rules of the game often forming a game position when taken together. Other bitboards are commonly used as masks to transform or answer queries about positions. The "game" may be any game-like system where information is tightly packed in a structured form with "rules" affecting how the individual units or pieces relate.
First you have to check if your PHP version supports 64bit integers, otherwise you will have strange results.
Just run:
echo PHP_INT_MAX;
and if result is 9223372036854775807 then it should work.
You're using strings and I suppose that when you'll do $string | $string in form like you're doing it above then it will be cast as integer with base 10, so the result won't be what you want. Since PHP 5.4 you can use 0b000 notation, for lower PHP version you'll need to keep it in hexadecimal or base 10 format. If you're storing values in DB or somewhere like that and you'll receive value as string or you just want to keep it in format presented above, then you have to use intVal($value, 2) first to cast it properly.
To iterate over the value you can use just for loop (as you suggested):
$value = intVal($WhitePieces,2);
for ($i = 0 ; $i < 64 ; ++$i) {
if ((pow(2,$i) & $value)) {
// draw piece
}
}
You do not have bitvalues, you do have strings. And strings should be difficult to or.
How do you loop? Use an array and foreach.
How do you use 64bit values? Use PHP 5.4 and the binary number format: 0b00001111 => 16 - alternatively express the integer value as hex or decimal, which should be completely ok for a game setup routine that will not change because the rules are known for centuries.
Remember that you have to use a 64Bit system to execute your code, otherwise PHP will be unable to support 64Bit integers, and either treat them as float values, or shorten them to 32Bit values, depending on what you actually do.
Because of all this, I'd suggest NOT to use bit fields for the solution. They seem like a great idea to program more assembler-like, but you are not writing assembler, and will probably pay for this approach with non-optimal performance compared to anything else.
Maybe the question is simple, but I can't find the answer.
What I need to do is to round number to 2 places after comma.
Im using this:
round(($data/$count*100), 2)
And when I get number like:
60.36036036036012 and : 37.83783783783808 is OK, because it's: 60.36 and 37.84
But why this:
1.8018018018018036
Is rounded to this:
1.8000000000000003
How to round always to 2 places, after comma?
You should get 1.8 unless you use something like old PHP version with some sort of related bugs. Still, if you want to see 1.80 you need to format output string, otherwise trailing zero will be stripped by default. The most flexible approach would be to use sprintf() formatting, like this:
$val = 1.8000000000000003;
printf("%.02f", round( $val, 2 ));
which would produce
1.80
The key is "%.02f" which means you want to format (f)loating point value, with two digits after dot, padded with 0 when needed (like this case).
See the sprintf() docs for more about available formatting possibilites.
Use PHP NumberFormatter class http://es.php.net/manual/es/class.numberformatter.php
I don't know why but the data type in this code makes a trouble when the id in the url starts with the number zero like this:
http://localhost/exp/update.php?id=03A43
In this case the id is 03A43.
And my query looks like this:
mysql_select_db("school", $con);
$result = mysql_query("SELECT * FROM student WHERE IDNO=".(int)$_GET['id']);
?>
There is no problem in the design if the id does not start with the number zero.
What might be the proper data type for numbers beginning in zero?
Edit: The OP didn't reveal until recently that the type of the field is a varchar, not a number. Hence, s/he should use this:
mysql_query("SELECT * FROM student WHERE IDNO='"
. mysql_escape_string($_GET['id']) . "'");
For posterity, my original answer was:
It looks like you're trying to parse a hexadecimal number, in which case you could do:
hexdec($_GET['id'])
(int)x is the same as intval(x), which defaults to base 10. Your number, 03A43, was clearly not base 10, so PHP stopped reading it when it got to the A. You could also say intval(x, 16) to parse the hexadecimal number, but since you're using the result as a string, hexdec is probably a teeny tiny bit faster.
As an unrelated note of caution, many programming languages treat numbers starting with 0 as octal rather than decimal. If you say $myvar = 031;, $myvar will be set to 25. This also applies to JavaScript as well as its parseInt function. In PHP, since (int) and intval default to base 10, intval('031') will be 31. However, intval('031', 0) will be 25 because the second parameter, 0, tells intval to autodetect the base.
Stop casting an alphanumeric string as an integer if you want the string to remain intact. Why are you doing that? Also, and more importantly, you need to escape your raw input, at the very least. Call mysql_real_escape_string() on it before passing it to mysql_query().
Quote your string:
mysql_select_db("school", $con);
$result = mysql_query("SELECT * FROM student WHERE IDNO='".$_GET['id']."'")
What's the type of student.IDNO in the database? Casting $_GET['id'] to an int is going to make it just "3", which seems like not what you want
(int)03A43 will output 3. Are you sure that's an A in there?
On the other hand, $_GET[] will always be a string. Casting a string as an int will remove the leading 0. If you need the leading 0 just don't cast it, leave the string as it is.