View Full Version : Adding values in single variable
letom
10-28-2013, 05:54 AM
$variable = 123 ;
? best method to retrieve the sum of the $variable as Eg - 1+2+3 = 6
jscheuer1
10-28-2013, 08:07 AM
I don't know if this is the best way. It is one way:
<?php
$variable = 123;
$va = str_split($variable);
$result = 0;
foreach ($va as $v){
$result += $v;
}
echo $result;
?>
djr33
10-28-2013, 09:58 AM
That would work (and for some reason it's appealing to me because I like foreach).
The best way would be to start with another kind of input (like an array).
The most efficient way* is as follows:
$n = 123;
$o=0;
for($i=0;$i+1<strlen($n);$i++) {
$o+=$n[$i];
}
echo $o; //5
This uses a trick where it treats this number as a string (technically, to not rely on a trick, you could convert it first), then it treats that string as an array of characters.
(*I'm talking about the shortest code to do this. For the most efficient machine processing, it's probably with while, imitating the for-loop, as you taught me a long time ago, John. You could obviously convert this one if you want.)
jscheuer1
10-28-2013, 01:28 PM
The trick doesn't work here. I get 0, and the correct result is 6 not 5, so you probably didn't try it out. Or if you did and got 5, it still doesn't work. This works:
<?php
$variable = 123;
$va = str_split($variable);
$result = 0;
$c = count($va);
while (--$c > -1){
$result += $va[$c];
}
echo $result;
?>
What you're calling a trick is known as type conversion. Various languages will or will not do it. Of those that will some will do it in one sort of circumstance and not another, sometimes without any immediately obvious reason. Both of my snippets rely upon type conversion as well. First that a number will be treated as a string and be split into an array, and second that the now string representations of the individual numbers will be treated as numbers when added to $result. In both cases this appears to go along fine. In your code I'm not sure where it doesn't convert as expected, or even if the lack of an expected type conversion is the problem. But, I get no errors and the result here for that code is 0.
Ah, if I type convert your $n:
$n = 123 . '';
Then it does work and gives 5, which is wrong because here:
for($i=0;$i+1<strlen($n);$i++) {
1 is added, which skips the first character/digit.
So I guess your's might 'work' in some version of PHP if it type converts within the loop. Mine (PHP 5.3) doesn't. It gives a null or falsey value to each $n[$i] in the loop.
It appears that, in my version of PHP at least, type conversion occurs number to string when an explicit string function is used upon a number, but not when a string convention ($str[$index]) is. String to number occurs in all of these, when they work, when using an arithmetic operator upon a string that can be a number.
djr33
10-28-2013, 06:48 PM
Sorry, I didn't test it. (And my math was off-- just quick in-my-head calculation... haha, I can't add.)
Right, if you type convert it with the empty string, it works.
I didn't realize that. I guess it's just slightly too much to use an integer as a string as an array. (Each conversion works independently though!)
As for the loop, just play with it a bit-- subtract one, add one, whatever works best. (Indices start at 0, strlen() is the number of characters, and we want it to go to one less than that-- I don't think the middle argument is the problem.)
If you can't figure it out I can check later. I'm just busy at the moment. This does work, in theory.
As I said in my last post, I prefer the foreach method because I know exactly what is going on there intuitively and wouldn't end up with typos like this :) (But technically this method is more efficient.)
<?php
$i = 123;
$sum_of_digits = array_sum( str_split( $i ) );
print $sum_of_digits; // 6
djr33
10-29-2013, 12:30 PM
Haha, that works. I wasn't even thinking about the sum, but about separating the digits. That's probably simplest. (Although at the most technical level, I don't know how efficient those functions are if speed is really the concern. I'm sure it would be fine. Addition isn't, in any way, very taxing on the system.)
jscheuer1
10-29-2013, 02:34 PM
In javascript we are taught that, if there's an internal method of doing something (native function), it's almost always more efficient than doing it yourself using more basic functions. So I would vote for Adrian's method as probably best. Time trials would need to be used to know for sure.
$variable = 123;
echo array_sum(str_split($variable));
In javascript we are taught that, if there's an internal method of doing something (native function), it's almost always more efficient than doing it yourself using more basic functions.
Which also holds true in PHP.
Time trials would need to be used to know for sure.
just for kicks:
Averages of multiple 1,000-iteration trials:
# my method
$variable = 123;
echo array_sum(str_split($variable));
# 0.0032110214233398 sec
# John's second method
$variable = 123;
$va = str_split($variable);
$result = 0;
$c = count($va);
while (--$c > -1){
$result += $va[$c];
}
# 0.0034551620483398 sec
# John's first method
$variable = 123;
$va = str_split($variable);
$result = 0;
foreach ($va as $v){
$result += $v;
}
# 0.0032589435577393 sec
...but, as you see, not much difference in this particular case. Two milliseconds between the fastest and slowest methods isn't very much. And remember, that's for 1,000 iterations.
djr33
10-30-2013, 06:32 AM
Isn't that 2 tenths of a millisecond?
Oddly enough, foreach is faster than while (or for) loops. I'm surprised. It's a sort of weird feature in PHP, but I love it. Now I like it more.
In javascript we are taught that, if there's an internal method of doing something (native function), it's almost always more efficient than doing it yourself using more basic functions.[/quote]
Which also holds true in PHP.[/quote]On average, and perhaps especially when PHP sometimes has default functions that are based in C++ (I think, and even if so I'm not sure which ones). But I'd imagine that sometimes it's overkill to use something-- for example, I imagined that foreach was a more complicated kind of loop. Here it turns out that particular example was wrong, of course. It was efficient.
By the way, letom, have we answered your question? You now have a few versions to pick from so you can use whatever you want. If you need more help, feel free to ask :)
Isn't that 2 tenths of a millisecond?
umm.... yes.
jscheuer1
10-30-2013, 12:48 PM
But only 1000 iterations over an array with only 3 members. Could be an anomaly, unless you ran each test 10 times and got the same result each time. Go 10000 times and make the string longer - like 50 digits. Then the results should be more definitive.
I did each test about a dozen times; what I posted was the average. There were some outliers. But, all in all, I didn't mean for it to be "definitive" anyway.
But, ask and ye shall receive: averages for 10,000 iterations, using PHP_INT_MAX (which, on my system (64 bit) was 9,223,372,036,854,775,807):
My method:
0.18127489089966 sec
John's first method:
0.20594382286072 sec
John's second method:
0.23329019546509 sec
jscheuer1
10-30-2013, 07:40 PM
I think foreach is faster than while in this case because while has to do a full array lookup each iteration. Using foreach is perhaps somehow more sequential and/or the array is in memory.
djr33
10-30-2013, 11:09 PM
In my imagination, foreach is a much more natural operation than for/while, but I haven't seen any evidence (until now) to support that. I don't know what kind of logic/math is actually behind it (I had always pessimistically assumed it was just a for loop using count(), roughly), but at least in theory I can imagine a very efficient mechanism that uses the array pointer to make it go faster-- in fact, I think that's exactly what's happening here. The array pointer is increased by one each time. Then by default it'll stop at the end of the array.
I don't know much about this, but I do know that arrays have points and that, if you do things the wrong way, they can actually mess things up-- like starting in the middle of the array next time, but only if you have very weird (and relatively low level / manual code, functions like reset() and friends).
I guess we're all just going to have to learn c++ and go find out. :)
jscheuer1
10-31-2013, 06:32 AM
I think Daniel and I are onto something. It seems fairly likely that since foreach means that the entire array is to be processed, the array is held in memory and the pointer is advanced incrementally for each iteration. Whereas, while and for loops are arbitrary. Each iteration could potentially involve anything. Just because the first iteration performs a lookup in an array, doesn't necessarily mean that same array will even be involved in the second iteration. So nothing is held in memory.
letom
10-31-2013, 01:55 PM
By the way, letom, have we answered your question? You now have a few versions to pick from so you can use whatever you want. If you need more help, feel free to ask :)
Noted with Thanks..
Powered by vBulletin® Version 4.2.2 Copyright © 2021 vBulletin Solutions, Inc. All rights reserved.