How to Convert/Round it off - php

I have some problem regarding converting/truncating a number.
This is the condition:
x.35 where x is any decimal number. If the decimal number is less than or equal to 35 then convert the .35 into 99 and subtract the x value with 1.
Something like this:
45.35 will become 44.99
Any help will be much more appreciated!

There's probably a faster way that doesn't use the explode function and other unnecessary things, but here's my rendition of it.
<?php
$input = 45.35; //input, obviously
$in2 = explode(".", $input);
if($in2[1] <= 35) {
$in2[1] = 99;
}
$output = $in2[0] . "." . $in2[1];
?>

Check out:
http://us.php.net/floor
http://us.php.net/ceil
http://us.php.net/round
Those should help
Following up on this, here's an example.
$val = 45.35;
$decimal = $val - floor($val);
if($decimal<.35) echo floor($val).".99";

Related

Numbers to letters with logical sequence

I have this array which links numbers to letters at the moment like this:
1-26 = A-Z
But there is more, 27=AA and 28=AB etc...
so basically when I do this:
var_dump($array[2]); //shows B
var_dump($array[29]); //shows AC
Now this array I made myself but it's becoming way too long. Is there a way to actually get this going on till lets say 32? I know there is chr but I dont think I can use this.
Is there an easier way to actually get this without using this way too long of an array?
It's slower calculating it this way, but you can take advantage of the fact that PHP lets you increment letters in the same way as numbers, Perl style:
function excelColumnRange($number) {
$character = 'A';
while ($number > 1) {
++$character;
--$number;
}
return $character;
}
var_dump(excelColumnRange(2));
var_dump(excelColumnRange(29));
here is the code which you are looking for :
<?php
$start = "A";
$max = 50;
$result = array();
for($i=1; $i<=$max; $i++) {
$result[$i] = $start++;
}
print_r($result);
?>
Ref: http://www.xpertdeveloper.com/2011/01/php-strings-unusual-behaviour/
This should work for you:
Even without any loops. First I calculate how many times the alphabet (26) goes into the number. With this I define how many times it has to str_repleat() A. Then I simply subtract this number and calculate the number in the alphabet with the number which is left.
<?php
function numberToLetter($number) {
$fullSets = (($num = floor(($number-1) / 26)) < 0 ? 0 : $num);
return str_repeat("A", $fullSets) . (($v = ($number-$fullSets*26)) > 0 ? chr($v+64) : "");
}
echo numberToLetter(53);
?>
output:
AAA

How to trim leading and trailing zeros in a number in PHP

I have the following numbers:
000000006375 and I want to output 63.75
000000004500 and I want to output just 45
Basically, if the last two numbers are not zero, I wanted to make it a float value wherein a decimal point will be added. But if the last 2 numbers are zeros I just want to output a whole number which in the example is just 45.
I was thinking of casting the numbers to int first but I do not know how to convert it to a float number if there last 2 digits are non-zeros.
You can use this code:
$s = '000000006375';
$i = (int) $s /100; // 63.75
echo "000000006375" / 100;
echo '<br />';
echo "000000004500" / 100;
// Output: 63.75<br />45
For your use case you might just cast it into an integer and divide with 100, like this:
$t1 = "000000006375";
$t2 = "000000004500";
var_dump(myfunc($t1), myfunc($t2));
function myfunc($in) {
$out = (int) $in / 100;
return $out;
}
The output will be something like...
float(63.75)
int(45)
print round('000000006375'/100,2);
print '<br/>';
print round('000000004500'/100,2);
$int = (int)'000000004500';
echo round((substr($int, 0, -2) . '.' . substr($int, -2)),2);
This is one way to do it :)

PHP string Computation

Im doing a php activity, that will compute the sum of given number of integer.
Sample Output:
int number = 367;
Final output
16
16 is the total sum of 3+6+7.
Here's my Code:
$number = "367";
$int = 0;
for ($i = 0 ; $i < number.length(); $i++ ){
$char = number.charAt(i);
$int += Integer.parseInt(char1.toString());
}
echo $int;
Still i can't get the right answer anyone can help me? Thank you !
regards jay
I'm not exactly sure what you're doing but it seems like you're mixing PHP and Javascript. If you're looking for a PHP solution it's a lot easier than that. Give this a try:
$number = 367;
echo array_sum(str_split($number));

PHP code for generating decent-looking coupon codes (mix of letters and numbers)

For an ecommerce site I want to generate a random coupon code that looks better than a randomly generated value. It should be a readable coupon code, all in uppercase with no special characters, only letters (A-Z) and numbers (0-9).
Since people might be reading this out / printing it elsewhere, we need to make this a simple-to-communicate value as well, perhaps 8-10 characters long.
Something like perhaps,
AHS3DJ6BW
B83JS1HSK
(I typed that, so it's not really that random)
$chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$res = "";
for ($i = 0; $i < 10; $i++) {
$res .= $chars[mt_rand(0, strlen($chars)-1)];
}
You can optimize this by preallocating the $res string and caching the result of strlen($chars)-1. This is left as an exercise to the reader, since probably you won't be generating thousands of coupons per second.
Try this:
substr(base_convert(sha1(uniqid(mt_rand())), 16, 36), 0, 10)
Why don't keep it simple?
<?php
echo strtoupper(uniqid());
?>
Always returns 13 character long uppercased random code.
You can use the coupon code generator PHP class file to generate N number of coupons and its customizable, with various options of adding own mask with own prefix and suffix. Simple PHP coupon code generator
Example:
coupon::generate(8); // J5BST6NQ
http://webarto.com/35/php-random-string-generator
Here you go.
function randr($j = 8){
$string = "";
for($i=0;$i < $j;$i++){
srand((double)microtime()*1234567);
$x = mt_rand(0,2);
switch($x){
case 0:$string.= chr(mt_rand(97,122));break;
case 1:$string.= chr(mt_rand(65,90));break;
case 2:$string.= chr(mt_rand(48,57));break;
}
}
return strtoupper($string); //to uppercase
}
If there are no security requirements for these, then you don't really need randomly generated codes. I would just use incremental IDs, such as those generated by whatever RDBMS you use. Optionally, if you have different types of coupons, you could prefix the codes with something, e.g.:
CX00019 QZ0001C
CX0001A QZ0001D
CX0001B QZ0001E
Alternately, you could even use dictionary words in the coupon, as such coupon codes are easier to remember and faster for users to type. Companies like Dreamhost use these for their promo codes, e.g.:
Promo60
NoSetupFee
YELLOWGORILLA82
Some of these are obviously human-created (which you might want to have the option of), but they can also be generated using a dictionary list. But even if they are randomly-generated nonsense phrases, the fact that the characters follow a logical pattern still makes it much more user-friendly than something like R7QZ8A92F1. So I would strongly advise against using the latter type of coupon codes just on the basis that they "look cool". Your customers will thank you.
$size = 12;
$string = strtoupper(substr(md5(time().rand(10000,99999)), 0, $size));
function generateCouponCode($length = 8) {
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$ret = '';
for($i = 0; $i < $length; ++$i) {
$random = str_shuffle($chars);
$ret .= $random[0];
}
return $ret;
}
you can find a lot of function in php rand manual
http://php.net/manual/en/function.rand.php
i like this one
<?php
//To Pull 8 Unique Random Values Out Of AlphaNumeric
//removed number 0, capital o, number 1 and small L
//Total: keys = 32, elements = 33
$characters = array(
"A","B","C","D","E","F","G","H","J","K","L","M",
"N","P","Q","R","S","T","U","V","W","X","Y","Z",
"1","2","3","4","5","6","7","8","9");
//make an "empty container" or array for our keys
$keys = array();
//first count of $keys is empty so "1", remaining count is 1-7 = total 8 times
while(count($keys) < 8) {
//"0" because we use this to FIND ARRAY KEYS which has a 0 value
//"-1" because were only concerned of number of keys which is 32 not 33
//count($characters) = 33
$x = mt_rand(0, count($characters)-1);
if(!in_array($x, $keys)) {
$keys[] = $x;
}
}
foreach($keys as $key){
$random_chars .= $characters[$key];
}
echo $random_chars;
?>
$length = 9;
$code = (strtoupper(substr(md5(time()), 0, $length)));
Just Write
$voucher_no = date('ymd') . rand(1000, 9999);
while(SapItem::where('voucher_no', $voucher_no)->exists()){
$voucher_no = date('ymd') . rand(1000, 9999);
}
Output: 2204171447

PHP convert decimal into fraction and back?

I want the user to be able to type in a fraction like:
1/2
2 1/4
3
And convert it into its corresponding decimal, to be saved in MySQL, that way I can order by it and do other comparisons to it.
But I need to be able to convert the decimal back to a fraction when showing to the user
so basically I need a function that will convert fraction string to decimal:
fraction_to_decimal("2 1/4");// return 2.25
and a function that can convert a decimal to a faction string:
decimal_to_fraction(.5); // return "1/2"
How can I do this?
Sometimes you need to find a way to do it and rounding is acceptable. So if you decide what range of rounding works out for you you can build a function like this. To convert a decimal into the fraction that it most closely matches. You can extend the accuracy by adding more denominators to be tested.
function decToFraction($float) {
// 1/2, 1/4, 1/8, 1/16, 1/3 ,2/3, 3/4, 3/8, 5/8, 7/8, 3/16, 5/16, 7/16,
// 9/16, 11/16, 13/16, 15/16
$whole = floor ( $float );
$decimal = $float - $whole;
$leastCommonDenom = 48; // 16 * 3;
$denominators = array (2, 3, 4, 8, 16, 24, 48 );
$roundedDecimal = round ( $decimal * $leastCommonDenom ) / $leastCommonDenom;
if ($roundedDecimal == 0)
return $whole;
if ($roundedDecimal == 1)
return $whole + 1;
foreach ( $denominators as $d ) {
if ($roundedDecimal * $d == floor ( $roundedDecimal * $d )) {
$denom = $d;
break;
}
}
return ($whole == 0 ? '' : $whole) . " " . ($roundedDecimal * $denom) . "/" . $denom;
}
I think I'd store the string representation too, as, once you run the math, you're not getting it back!
And, here's a quick-n-dirty compute function, no guarantees:
$input = '1 1/2';
$fraction = array('whole' => 0);
preg_match('/^((?P<whole>\d+)(?=\s))?(\s*)?(?P<numerator>\d+)\/(?P<denominator>\d+)$/', $input, $fraction);
$result = $fraction['whole'] + $fraction['numerator']/$fraction['denominator'];
print_r($result);die;
Oh, for completeness, add a check to make sure $fraction['denominator'] != 0.
To can use PEAR's Math_Fraction class for some of your needs
<?php
include "Math/Fraction.php";
$fr = new Math_Fraction(1,2);
// print as a string
// output: 1/2
echo $fr->toString();
// print as float
// output: 0.5
echo $fr->toFloat();
?>
Here is a solution that first determines a valid fraction (although not necessarily the simplest fraction). So 0.05 -> 5/100. It then determines the greatest common divisor of the numerator and denominator to reduce it down to the simplest fraction, 1/20.
function decimal_to_fraction($fraction) {
$base = floor($fraction);
$fraction -= $base;
if( $fraction == 0 ) return $base;
list($ignore, $numerator) = preg_split('/\./', $fraction, 2);
$denominator = pow(10, strlen($numerator));
$gcd = gcd($numerator, $denominator);
$fraction = ($numerator / $gcd) . '/' . ($denominator / $gcd);
if( $base > 0 ) {
return $base . ' ' . $fraction;
} else {
return $fraction;
}
}
# Borrowed from: http://www.php.net/manual/en/function.gmp-gcd.php#69189
function gcd($a,$b) {
return ($a % $b) ? gcd($b,$a % $b) : $b;
}
This includes a pure PHP implementation of the gcd although if you are sure the gmp module is installed you could use the one that comes with gcd.
As many others have noted you need to use rational numbers. So if you convert 1/7 to a decimal then try to convert it back to a decimal you will be out of luck because the precision lost will prevent it from getting back to 1/7. For my purposes this is acceptable since all the numbers I am dealing with (standard measurements) are rational numbers anyway.
Buddies, can this help?
[]s
function toFraction($number) {
if (!is_int($number)) {
$number = floatval($number);
$denominator = round(1 / $number);
return "1/{$denominator}";
}
else {
return $number;
}
}
Little improvement on above, but keepin it simple.
function dec2frac($f) {
$base = floor($f);
if ($base) {
$out = $base . ' ';
$f = $f - $base;
}
if ($f != 0) {
$d = 1;
while (fmod($f, 1) != 0.0) {
$f *= 2;
$d *= 2;
}
$n = sprintf('%.0f', $f);
$d = sprintf('%.0f', $d);
$out .= $n . '/' . $d;
}
return $out;
}
An approach would be to retrieve the decimal value and multiply it by 2, 3, 4 and so on until you get an integer number.
However, I'd stick with the answer given by Derek. Guess what happens when a user inserts n/(n+1) with n high. Such an algorithm would have to scan all the numbers up to n+1.
Not to mention it is likely you'll end up with approximation problems.
You'll have to face a serious problem, because floats are not precise enough.
When you'll have to deal with 1.3333, PHP will make an estimate of this value... So you will never be able to convert it to 1 1/3.
It seems to be simple to overcome, but if you want your program to differentiate 1/7901 (~ 1,2656625743576762435134793064169e-4) with 1/7907 (~
1,2647021626406981155937776653598e-4) precisely... this will be a real hell !!
IMHO, if you want to deal with maths, you should rely on an external library... or try to make PHP communicate with Matlab.
If you want to know more, i suggest you dig in floating point problems... Starting with wikipedia.
A variation of Jir's approach could actually work if only a limited amount of denominators are used : multiply everything by the least common denominators (and round the result to discard any remaining decimals due to approximation).
I.e.: if you only have to deal with halfs, thrids and quarters, just multiply everything by 12.
And also if you know the common denominator, this should greatly reduce the search speed by knowing exactly which numbers to search instead of searching all n+1 possible.
If you have to deal with lots of unusual fractions, like 1/7, 1/13, etc. well, stick to Derek's solution and store the original value too.
The fraction to decimal is quite straightforward and there are lots of solutions. I'd go with trimming the string, replacing spaces with '+', and anything other than space,/,. or digits with '' then running it through 'eval'.
The decimal to fraction is virtually impossible to do correctly - not least because your decimal fraction would probably have to be converted to binary first - at which point you loose a lot of precision. As an academic exercise.....If you can live with the difference between 20976/41953 and 1/2 then you could try a fuzzy match for a predefined number of fractions:
(there's probably a neater way of implementing the same algorithm - but I'll leave that as an exercise for the reader).
define('DECIMAL_DIGITS',5);
function decimal_2_frac($inp_decimal)
{
static $fracs;
if (!is_array($fracs)) {
init_fracs($fracs);
}
$int_part=(integer)$inp_decimal;
$inp_decimal=$inp_decimal-$int_part;
$candidate='';
$distance=10;
foreach ($fracs as $decimal=>$frac) {
if (abs($decimal-$inp_decimal)<$distance) {
$candidate=$frac;
$distance=abs($decimal-$inp_decimal);
}
if (abs($decimal-$inp_decimal)>$distance) {
break;
}
}
return $int_part . ' ' . $candidate;
}
function init_fracs(&$fracs)
{
$fracs=array();
for ($x=2;$x<(5*DECIMAL_DIGITS);$x++) {
// there's probably a beter way to calculate the loop limit
for ($y=1; $y<$x; $y++) {
$decimal=round($y/$x,DECIMAL_DIGITS);
$frac="$x/$y";
if (!array_key_exists($decimal,$fracs)) {
$fracs[$decimal]=$frac;
}
}
}
}
But personally, I'd just store the original representation in a seperate field in the database.
function dec2frac($f)
{
$d = 1
while (fmod($f, 1) != 0.0) {
$f *= 2;
$d *= 2;
}
$n = sprintf('%.0f', $f);
$d = sprintf('%.0f', $d);
return array($n, $d);
}
Then $f == $n / $d
For example:
print_r(dec2frac(3.1415926));
Outputs:
Array
(
[0] => 3537118815677477 // $n
[1] => 1125899906842624 // $d
)
I made a blog post with a couple solutions for this, the most recent approach I took is:
http://www.carlosabundis.com/2014/03/25/converting-decimals-to-fractions-with-php-v2/
function dec2fracso($dec){
//Negative number flag.
$num=$dec;
if($num<0){
$neg=true;
}else{
$neg=false;
}
//Extracts 2 strings from input number
$decarr=explode('.',(string)$dec);
//Checks for divided by zero input.
if($decarr[1]==0){
$decarr[1]=1;
$fraccion[0]=$decarr[0];
$fraccion[1]=$decarr[1];
return $fraccion;
}
//Calculates the divisor before simplification.
$long=strlen($decarr[1]);
$div="1";
for($x=0;$x<$long;$x++){
$div.="0";
}
//Gets the greatest common divisor.
$x=(int)$decarr[1];
$y=(int)$div;
$gcd=gmp_strval(gmp_gcd($x,$y));
//Calculates the result and fills the array with the correct sign.
if($neg){
$fraccion[0]=((abs($decarr[0])*($y/$gcd))+($x/$gcd))*(-1);
}else{
$fraccion[0]=(abs($decarr[0])*($y/$gcd))+($x/$gcd);
}
$fraccion[1]=($y/$gcd);
return $fraccion;
}
Just adding a bit more logic to Derek's accepted answer - check for "division by zero" and whole number input check.
function fractionToDec($input) {
if (strpos($input, '/') === FALSE) {
$result = $input;
} else {
$fraction = array('whole' => 0);
preg_match('/^((?P<whole>\d+)(?=\s))?(\s*)?(?P<numerator>\d+)\/(?P<denominator>\d+)$/', $input, $fraction);
$result = $fraction['whole'];
if ($fraction['denominator'] > 0)
$result += $fraction['numerator'] / $fraction['denominator'];
}
return $result;
}
function frac2dec($fraction) {
list($whole, $fractional) = explode(' ', $fraction);
$type = empty($fractional) ? 'improper' : 'mixed';
list($numerator, $denominator) = explode('/', $type == 'improper' ? $whole : $fractional);
$decimal = $numerator / ( 0 == $denominator ? 1 : $denominator );
return $type == 'improper' ? $decimal : $whole + $decimal;
}
Use a 3rd party library, for example:
https://packagist.org/packages/phospr/fraction
Usage:
$fraction = Fraction::fromFloat(1.5);
echo "Fraction is: " . $fraction->getNumerator() . '/' . $fraction->getDenominator();
echo "Float is: " . $fraction->toFloat();
I usually do a quick search on https://packagist.org to see if something already exists to solve what I'm trying to do, if so then I can take advantage of the many hours that the community have already put into solving the problem (this will be much much more time than I'll be able to dedicate to it) and it will also be more likely to be bug free, having been battle tested by others and maybe even have a test suite covering it.
Saves time and results in higher quality.

Categories