Getting different results when adding numbers - php

I'm currently doing some simple addition of decimal numbers in PHP (currency), but for some reason I can add the same numbers twice and get different results.
What I'm doing is getting some rows from a MySQL table in PHP, adding the total for each receipt and storing the result in another MySQL table as decimal(10,2):
<?php
foreach($query_result as $row) {
$total_receipts = $total_receipts + $row['total'];
//my locale requires commas as decimal separators and points for thousands:
echo number_format($total_receipts,2,",",".");
}
?>
The strange thing is I can do the same operation twice on the exact same rows and get two different results, with regard to the decimal point. For example, when I add the following numbers:
3621.94
1230.29
1025.00
1025.00
The first time the correct value of 6902.23 was inserted in the DB. When I ran it the second time, the value inserted in the DB was 6.90.
For some reason, the second time around it decided to move the decimal point.
I'm not using number_format() to insert in to the DB , I'm storing $total_receipts without modifications.
In this particular example the error appeared in the second try, but sometimes it can show up the first time and the second time be correct.Sometimes I cannot even replicate the bug.
What am I doing wrong? I've been reading about bcmath, but I'm not sure if I should be using it for this simple addition.

Please use number_format() to insert into DB:
<?php
$total_receipts = 0; //Always initialize vars
foreach($query_result as $row) {
$total_receipts += $row['total'];
//this way to insert into DB
echo number_format($total_receipts, 2, ".", "");
}
?>

Related

Echo repeated variables loop php

you see, I have these variables that are set within a While, I'm using MySQL also, What I want to do is to sort of "Group" those variables into one, and then the rest of the variables that are not repeated, i want to assign them "Display:none" So , look at this image:
Now, as you can see there is two duplicate dates, but the values are different, so in this case (Take in mind that I only want to group these "Recibos" but dont worry about it) you can see in the first row it has a different date, and has no repeated dates, while the last two of "Recibos" is sort of duplicated
Basically what I want to do is to group the two last "Recibos" (The duplicate dates), only one of the same date has to appear, and the rest of them, are gonna be shown when the TR is hover
Though , I only want a simple version of what I want, it can be some sort of testing, as you can see in this image, i've been trying for weeks and still didnt get anything, I hope you can help me! thanks in advance
I have made this code, which is the one in the image above:
Inside the while:
$acumulado-=$monto;
if(($fila>=$mostrar_de_aca_en_adelante && $detalles=='minimo') || ($detalles=='maximos')){
$conteo++;
$string_fecha[$conteo] = $fecha_operacion;
$string_fecha_tmp[$conteo] = $fecha_operacion;
$recibo_id_cliente[$conteo]=$id_cliente;
$recibo_monto[$conteo]=$monto;
$recibo_saldo_total[$conteo]=$saldo_total;
$recibo_detalle_movimiento[$conteo]=$datos_detalles['detalle_movimiento'];
$recibo_recibo[$conteo]=$recibo[0];
$recibo_verificado[$conteo]=$datos_detalles['verificado'];
$recibo_acumulado[$conteo]=$acumulado;
$label = $monto;
}
Outside the while:
echo "<br><br><br>";
for($i = 1; $i <= $conteo; $i++){
if($string_fecha[$i] == $string_fecha_tmp[($i + 1)]){
$label += $recibo_monto[$i];
$string_imprime_tmp .= "<br>[Repetido]".$string_fecha[$i]."(".$label.")";
}
}
echo $string_imprime_tmp;
var_dump($string_fecha);
By the way: I know this can be done in MySQL, but it can only be done in php i'm limited to php.

Compare one by one characters from a mysql db with php

I'm trying to compare in my DB a row with another character by character and give as a result the id which best fits the given data. For example I have on my DB the user David with a AAA sequence and I want to compare it with one I give in which is a ABA so I'd like to receive a percentage (66.6% in this case) of match,
I have done until here but don't know how to go on:
$uname = $_POST['sequence'];
$query = "SELECT name FROM dna WHERE sequence = '$uname'";
$result = mysql_query($query);
while($row = mysql_fetch_array($result))
{
echo $row['name'];
}
In order to get the similarity in percent, you might use the PHP function similar_text().
The two strings are compared and the similarity percentage is returned, if the third parameter is passed to the function.
$string_1 = 'AAA';
$string_2 = 'ABA';
similar_text($string_1, $string_2, $percent);
echo $percent;
// 66.666666666667
The database part is a bit more work. A very basic implementation could look like this.
Keep in mind, that the real problem is, that you compare a string against 1 million rows.
In general: one wouldn't do that, because instead of chars, there a bits. And to compare bits, you would use simply bit-shifts. Anyway...
Here, when working with chars/strings, a rolling row requests or limited query could help, too.
That would mean, that you ask the db for chunks of let's say 500 rows and do the calc work.
It depends on the number of rows and the memory use of the dataset.
// incomming via user input
$string_1 = $_POST['sequence'];
// temporary var to store the highest similarity percentage and it's row_id
$bestValue = array('row_id' => 0, 'similarity' => '0');
// iterate over the "total number of rows" in the database
foreach($rows as $id => $row)
{
// get a new string_2 from db
$string_2 = $row['name'];
// calculate similarity
similar_text($string_1, $string_2, $percent);
// if calculated similarity is higher, then update the "best" value
if($percent > $bestValue['similarity']) {
$bestValue = array('row_id' = $id, 'similiarity' = $percent);
}
}
var_dump($bestValue);
After all db rows are processed, bestValue will containg the highest percentage and it's row id.
You can do all kinds of things here, for instance:
switch from first match update (<) to last match update (<=)
stop iteration on first match
store row_id's, which have the same similarity (multi row match)
if you don't need multi row match, you might drop the array and use two vars for row and percent
proper error handling, escaping, mysqli usage
Be warned: this isn't the most efficient approach, especially not, when working with large datasets. If you need this on a level, which is not hobby or homework, then simply pull a tool, which is optimized for this job, like EMBOSS (http://emboss.sourceforge.net/).

Can't insert decimal value with PDO

I've been trawling the web for hours now and trying different methods, and I can't work out why PDO can't insert any row where one of the values contains a decimal.
For example, if the value entered into the cost field has no decimal value then it works fine. But anything like with a decimal and it just ignores the whole row.
200 works, even 200.00 works. But things like 39.99 don't.
Here's the code:
$invoice_id = $db->lastInsertId('id');
$item_name = $_POST['item_name'];
$item_qty = $_POST['item_qty'];
$item_cost = $_POST['item_cost'];
$item_vat = $_POST['item_vat'];
for($i = 0; $i < count($item_name); $i++) {
$item_query = $db->prepare("INSERT INTO hm_invoice_items(invoice, item, qty, amount, vat) VALUES(:invoice, :item, :qty, :amount, :vat)");
$item_query->bindParam(":invoice", $invoice_id);
$item_query->bindParam(":item", $item_name[$i]);
$item_query->bindParam(":qty", $item_qty[$i]);
$item_query->bindParam(":amount", $item_cost[$i]);
$item_query->bindParam(":vat", $item_vat[$i]);
if (!$item_query->execute())
{
die(showMessage("There has been a problem adding the invoice items.", "Error!"));
}
}
A var_dump tells me that the insert query is receiving the values, but it does not like dealing with decimals.
There could be an issue with decimal separator.
When debugging such cases it's essential to var_dump() e-ve-ry-thing!
Why don't you var_dump your values for the closer inspection?
Why didn't you play with decimals only, without POST, without other values?
A question titled "Can't insert decimal value with PDO" should contain short reproduceable code with decimal value present to readers and the result.
Judging by indirect measures will do no help for you and - especially - won't bring you help from strangers.
"var_dump your values" means every suspicious value, like
var_dump($item_cost[$i]);
inside your loop
if you get no output - then there is empty value, so, no wonder nothing inserted.
By the way, you're binding apparently decimal item_cost value to apparently integer amount field. Is it a typo?
But again - where is a certain reproduceable proofcode contains one insert query, one hardcoded decimal value and one result? Ugh - and table definition of course.
Try this?
$item_query->bindParam(":amount", floatval($item_cost[$i]));
At least it works for me when I deal with MySQL decimal data type with PDO.
Use the following to display the content of all the values POSTed to your PHP script:
print_r($_POST);

PHP."INSERT INTO" run twice via PHP mysqli_query!

for($j = 0 ; $j < 87; $j++){
echo $j.'<br/>';
$unique = mt_rand(0,100000000);
$insert_data = 'INSERT INTO uniques(uniq) VALUES ("'.$unique.'")';
mysqli_query($conn , $insert_data);
echo $unique.'<br />';
}
I just want to insert random number into table uniques. But something wrong with above code.It worked fine when total loop under 86 and got twice insert when looping above 86.
Thank you very much!
I don't mean I got duplicate random number. But it seems the "INSERT INTO" run twice in my php code!
mt_rand(0,100000000) just returns a random number between 1 and 100000000 it does not keep track of the previously generated random numbers hence you can get duplicates.
If you want to make sure that you only insert unique values in the DB, you'll have to keep the history of the generated random numbers and keep calling mt_rand till you get a unique one.
As you need unique numbers, you may find the samples here of help
http://www.php.net/manual/en/function.mt-rand.php#83365
Alternately you could use a where clause to avoid duplicates, but this could be slow if you are adding a large number of records.

Numbers and calculations in php/sql

ok im new on the scene with php and sql, i read the basics and was able to produce a DB driven shoutbox.
This is my website http://www.teamdelta.byethost12.com/
What i want to do next im not sure what i should be using java? php? sql? i have no idea...
but i assume php and sql if sql can do what i think it can..
What i want to do next is to A extract data from data at certain positions for example
data in the format "DAB:CD:EF:GH" eg "D03:57:16:23" to be turned into AB, DF, CE. Eg "3","76","51".
then i want to store these Numbers (Not VARCHARS) in the database.
that is part 1.
the sceond part that i want to make sure is possible before i put to much effort in is to do calculations on all the entries in the database with respect to a 3rd peice of data and display all the entries in a decending ordered list ordered by the output of the calculation..
i think calculations can be added to querys...but as i said im new and the tutorial i read only coved reading values out of the db..
and just if it helps to clarify what im trying to do even though this is not part of the question... here is what im trying to do
* set up a database and entry system that records the player name, base name, location,econ, and comment and stored this as a entry in the database..(i have done this)
*on entry i wish to extract numeric values(AB,DF,CE) from a text string(location) (dont know how)
*then i wish to display the list(i have done this)
*a new column should be added on display containing the resuly of a calculation involving the numberic values from each entry with a global value that is entered on page(dont know how)
*then the list should be sorted in decending order of the output of the calculation.
*lastly i wish to be able to remove items from the list with a click.
thats all :) ,, seeking part advice and guidence
here is the page its php but i renamed it as text so its readble.
cant past is as code as it has escape chars in it
http://www.teamdelta.byethost12.com/trade/postroute3.txt
currently trying to use
$values = array();
$string = $location;
$values[0]= $string[1].$string[2];
$values[1]= $string[5].$string[8];
$values[2]= $string[4].$string[7];
$x = intval($values[1], 10);
$y = intval($values[2], 10);
$g = intval($values[0], 10);
print_r($x);
echo(' : '); print_r($y); echo(' : ');
print_r($g);
ok.. for the first part.
$values = array();
$values = split(":", 'DAB:CD:EF:GH');
$int_values = array();
foreach($values as $v) {
$int_values[] = intval($v, 10);
}
// values in base 10
print_r($int_values);

Categories