# fmod

(PHP 4 >= 4.2.0, PHP 5)

fmodВозвращает дробный остаток от деления по модулю

### Описание

float fmod ( float `\$x` , float `\$y` )

Возвращает дробный остаток от деления делимого (`x`) и делителя (`y`). Остаток (r) определяется так: x = i * y + r, где i - некоторое целое. Если `y` не равен нулю, то r имеет такой же знак, как `x` и величину, меньшую или равную величине `y`.

`x`

Делимое.

`y`

Делитель.

### Возвращаемые значения

Остаток от операции деления `x`/`y`

### Примеры

Пример #1 Пример использования fmod()

``` <?php\$x = 5.7;\$y = 1.3;\$r = fmod(\$x, \$y);// \$r равно 0.5, потому что 4 * 1.3 + 0.5 = 5.7?> ```

## Коментарии

``` NAN (.net Equivalent = Double.NaN) means "Not-a-Number". Some ways to get NaN are modulo 0, and square root of 0. ```
2003-03-09 17:57:47
http://php5.kiev.ua/manual/ru/function.fmod.html
``` Integer Modulo If you want the remainder of the division of two Integers rather than Floats, use "%"; eg: <?php \$a = 4; \$b = 3; print(\$a % \$b); ?> Will output "1". ```
2004-02-16 15:19:37
http://php5.kiev.ua/manual/ru/function.fmod.html
``` If you need to reduce an integer to zero if zero and 1 if not, you can use \$sign = (integer)(boolean)\$integer; instead of \$sign = \$integer > 0 ? 1 : 0; it is faster from 100 operations on (at least on my machine). ```
2004-05-27 11:10:51
http://php5.kiev.ua/manual/ru/function.fmod.html
``` fmod() does not mirror a calculator's mod function. For example, fmod(.25, .05) will return .05 instead of 0 due to floor(). Using the aforementioned example, you may get 0 by replacing floor() with round() in a custom fmod(). <? function fmod_round(\$x, \$y) {     \$i = round(\$x / \$y);     return \$x - \$i * \$y; } var_dump(fmod(.25, .05)); // float(0.05) var_dump(fmod_round(.25, .05)); // float(0) ?> ```
2005-01-10 13:44:49
http://php5.kiev.ua/manual/ru/function.fmod.html
``` john at digitizelife dot com: Well not sure how your comment applys to fmod..  but their is a sure simpler way of coping with situations like this..  its called a bit field (bit masking)   e.g. /* Categories */ bin     dec   cat 0001 - 1 - Blue  0010 - 2 - Red  0100 - 4 - Green  1000 - 8 - Yellow /* Permissions */ 0010 - 2   - Bob 0101 - 5    - John 1011 - 11  - Steve 1111-  15 - Mary to find out the permissions for each user you simple need to do a bitwise AND  \$steve_auth=11; function get_perm(\$auth) {     \$cats["Blue"]=1;     \$cats["Red"]=2;     \$cats["Green"]=4;     \$cats["Yellow"]=8;     \$perms=array();     foreach(\$cats as \$perm=>\$catNum)     {           if(\$auth & \$catNum)                 \$perms[\$perm]=true;     }     return \$perms; } print_r(get_perm(\$steve_auth)); /* returns  Array (     [Blue] => 1     [Red] => 1     [Yellow] => 1 ) */ This is far simpler than your prime number idea, in fact you dont even need a function in any tests for the permmsions on a user you can do them directly using the bitwise and operator. You may want to read the following  http://en.wikipedia.org/wiki/Bitmask http://uk2.php.net/manual/en/language.operators.bitwise.php ```
2005-02-19 20:10:32
http://php5.kiev.ua/manual/ru/function.fmod.html
``` Just a note on the previous note by Ryan Means: Instead of using explode() to get the number before the decimal point, would be to use floor()... floor() rounds fractions down, which is exactly what is needed. His same example using floor(); <?PHP \$totalsec=XXXXXXX; //Replace the X's with a int value of seconds \$daysarray = floor( \$totalsec/86400 ); \$partdays = fmod(\$totalsec, 86400); \$hours = floor( \$partdays/3600 ); \$parthours = fmod(\$partdays, 3600); \$min = floor( \$parthours/60 ); \$sec = fmod(\$parthours, 60); echo "days " . \$days . "<br>"; echo "hours " . \$hours . "<br>"; echo "minutes " . \$min . "<br>"; echo "seconds " . \$sec . "<br>"; ?> ```
2005-11-22 19:39:56
http://php5.kiev.ua/manual/ru/function.fmod.html
``` A more formal way for generating duration strings: <?php function duration( \$int_seconds=0, \$if_reached=null ) {     \$key_suffix = 's';     \$periods = array(                     'year'        => 31556926,                     'month'        => 2629743,                     'day'        => 86400,                     'hour'        => 3600,                     'minute'    => 60,                     'second'    => 1                     );     // used to hide 0's in higher periods     \$flag_hide_zero = true;     // do the loop thang     foreach( \$periods as \$key => \$length )     {         // calculate         \$temp = floor( \$int_seconds / \$length );         // determine if temp qualifies to be passed to output         if( !\$flag_hide_zero || \$temp > 0 )         {             // store in an array             \$build[] = \$temp.' '.\$key.(\$temp!=1?'s':null);             // set flag to false, to allow 0's in lower periods             \$flag_hide_zero = false;         }         // get the remainder of seconds         \$int_seconds = fmod(\$int_seconds, \$length);     }     // return output, if !empty, implode into string, else output \$if_reached     return ( !empty(\$build)?implode(', ', \$build):\$if_reached ); } ?> Simple use: <?php     echo duration( mktime(0, 0, 0, 1, 1, date('Y')+1) - time(), 'Some fancy message to output if duration is already met...' ); ?> Enjoy. :-) ```
2005-11-26 02:38:46
http://php5.kiev.ua/manual/ru/function.fmod.html
``` Note on the code given by cory at lavacube dot net. You will recieve better results by not using floor and using round instead. As you continue increasing to larger amounts of time you will notice that the outputted time is off by large amounts. so instead of \$temp = floor( \$int_seconds / \$length ); we would use  \$temp = round( \$int_seconds / \$length ); <?php function duration( \$int_seconds=0, \$if_reached=null ) {    \$key_suffix = 's';    \$periods = array(                    'year'        => 31556926,                    'month'        => 2629743,                    'day'        => 86400,                    'hour'        => 3600,                    'minute'    => 60,                    'second'    => 1                    );    // used to hide 0's in higher periods    \$flag_hide_zero = true;    // do the loop thang    foreach( \$periods as \$key => \$length )    {        // calculate        \$temp = round( \$int_seconds / \$length );        // determine if temp qualifies to be passed to output        if( !\$flag_hide_zero || \$temp > 0 )        {            // store in an array            \$build[] = \$temp.' '.\$key.(\$temp!=1?'s':null);            // set flag to false, to allow 0's in lower periods            \$flag_hide_zero = false;        }        // get the remainder of seconds        \$int_seconds = fmod(\$int_seconds, \$length);    }    // return output, if !empty, implode into string, else output \$if_reached    return ( !empty(\$build)?implode(', ', \$build):\$if_reached ); } ?> ```
2005-11-27 00:16:10
http://php5.kiev.ua/manual/ru/function.fmod.html
``` I don't believe that is correct. Try this out using your patch: <?php echo duration( mktime(0, 0, 0, 1, 0, 2006)-time() ); ?> As of right now, this will read: 1 month, 22 days, 24 hours, 49 minutes, 15 seconds Which is completely incorrect. Seeing as how it is the 9th of December. The real real flaw here is how the 'year' and 'month' periods are calculated. As most months vary in length... Thank you very much SnakeEater251 for pointing this out. The quickest way to get slightly more accurate results, is to use averages based on one "true" year, which is 365.25 days. Change the year and month to:       'year'       => 31557600, // one 'true year' (365.25 days)       'month'    => 2629800, // one 'true year' divided by 12 :-) I will work on developing a true fix, for pin-point accuracy. ;-)  - Cory Christison ```
2005-12-09 00:13:10
http://php5.kiev.ua/manual/ru/function.fmod.html
``` Please note that this: <?php function custom_modulo(\$var1, \$var2) {   \$tmp = \$var1/\$var2;   return (float) ( \$var1 - ( ( (int) (\$tmp) ) * \$var2 ) ); } \$par1 = 1; \$par2 = 0.2; echo "fmod:          "; var_dump(fmod ( \$par1 , \$par2 )); echo "custom_modulo: "; var_dump(custom_modulo ( \$par1 , \$par2 )); ?> gives this: fmod:          float(0.2) custom_modulo: float(0) Fmod does not deliver the desired result, therefore I made my own. ```
2007-07-01 12:37:26
http://php5.kiev.ua/manual/ru/function.fmod.html
``` I always use this: function modulo(\$n,\$b) { return \$n-\$b*floor(\$n/\$b); } And it appears to work correctly. ```
2008-05-20 15:09:45
http://php5.kiev.ua/manual/ru/function.fmod.html
``` You can also use the modulo operator '%', which returns the same result : <?php \$var1 = 5; \$var2 = 2; echo \$var1 % \$var2; //Returns 1 echo fmod(\$var1,\$var2); //Returns the same ?> ```
2009-10-18 08:49:25
http://php5.kiev.ua/manual/ru/function.fmod.html
``` This class ran through several unit tests and fixes all failures found in bugs.php.net <?php abstract class MyNumber {     public static function isZero(\$number, \$precision = 0.0000000001)     {         \$precision = abs(\$precision);         return -\$precision < (float)\$number && (float)\$number < \$precision;     }     public static function isEqual(\$number1, \$number2)     {         return self::isZero(\$number1 - \$number2);     }     public static function fmod(\$number1, \$number2)     {         \$rest = fmod(\$number1, \$number2);         if (self::isEqual(\$rest, \$number2)) {             return 0.0;         }         if (mb_strpos(\$number1, ".") === false) {             \$decimals1 = 0;         } else {             \$decimals1 = mb_strlen(\$number1) - mb_strpos(\$number1, ".") - 1;         }         if (mb_strpos(\$number2, ".") === false) {             \$decimals2 = 0;         } else {             \$decimals2 = mb_strlen(\$number2) - mb_strpos(\$number2, ".") - 1;         }         return (float)round(\$rest, max(\$decimals1, \$decimals2));     } } ?> ```
2010-02-10 08:37:25
http://php5.kiev.ua/manual/ru/function.fmod.html
``` Note that fmod is NOT equivalent to this basic function: <?php  function modulo(\$a, \$b) {     return \$a - \$b * floor(\$a / \$b);  } ?> because fmod() will return a value with the same sign as \$a. In other words the floor() function is not correct as it rounds towards -INF instead of towards zero. To emulate fmod(\$a, \$b) the correct way is: <?php  function fmod(\$a, \$b) {    return \$a - \$b * ((\$b < 0) ? ceil(\$a / \$b) : floor(\$a / \$b)));  } ?> Note that both functions will throw a DIVISION BY ZERO if \$b is null. The first function modulo() above is the mathematical function which is useful for working on cyclic structures (such as calender computions or trignonometric functions : - fmod(\$a, 2*PI) returns a value in [0..2*PI) if \$a is positive - fmod(\$a, 2*PI) returns a value in [-2*PI..0] if \$a is negative - modulo(\$a, 2*PI) returns a value always in [0..2*PI) independantly of the sign of \$a ```
2012-12-12 04:38:48
http://php5.kiev.ua/manual/ru/function.fmod.html
``` There is an elegant way to do compute gcm : https://en.wikipedia.org/wiki/Greatest_common_divisor     // Recursive function to compute gcd (euclidian method)     function gcd (\$a, \$b) {         return \$b ? gcd(\$b, \$a % \$b) : \$a;     }     // Then reduce any list of integer     echo array_reduce(array(42, 56, 28), 'gcd'); // === 14 If you want to work with floating points, use approximation :     function fgcd (\$a, \$b) {         return \$b > .01 ? fgcd(\$b, fmod(\$a, \$b)) : \$a; // using fmod     }     echo array_reduce(array(2.468, 3.7, 6.1699), 'fgcd'); // ~= 1.232 You can use a closure in PHP 5.3 :     \$gcd = function (\$a, \$b) use (&\$gcd) { return \$b ? \$gcd(\$b, \$a % \$b) : \$a; }; ```
2013-07-06 01:33:38
http://php5.kiev.ua/manual/ru/function.fmod.html
``` To create a list of primes in a bash based on php wich can be resumed after breaking I did use fmod() and some snippets offered by two more users here on php comments. This will output : "prime;difference-between-last-and-current-prime" So credit goes to them. I only did the logfile output. This will function up to whatever fmod supports as highest value. Just enter the \$end value. And do a touch to the logfile followed by chmod 666 so php can access it. <?php  function tailCustom(\$filepath, \$lines = 1, \$adaptive = true) {           // Open file         \$f = @fopen(\$filepath, "rb");         if (\$f === false) return false;           // Sets buffer size         if (!\$adaptive) \$buffer = 4096;         else \$buffer = (\$lines < 2 ? 64 : (\$lines < 10 ? 512 : 4096));           // Jump to last character         fseek(\$f, -1, SEEK_END);           // Read it and adjust line number if necessary         // (Otherwise the result would be wrong if file doesn't end with a blank line)         if (fread(\$f, 1) != "\n") \$lines -= 1;                 // Start reading         \$output = '';         \$chunk = '';           // While we would like more         while (ftell(\$f) > 0 && \$lines >= 0) {               // Figure out how far back we should jump             \$seek = min(ftell(\$f), \$buffer);               // Do the jump (backwards, relative to where we are)             fseek(\$f, -\$seek, SEEK_CUR);               // Read a chunk and prepend it to our output             \$output = (\$chunk = fread(\$f, \$seek)) . \$output;               // Jump back to where we started reading             fseek(\$f, -mb_strlen(\$chunk, '8bit'), SEEK_CUR);               // Decrease our line counter             \$lines -= substr_count(\$chunk, "\n");           }           // While we have too many lines         // (Because of buffer size we might have read too many)         while (\$lines++ < 0) {               // Find first newline and remove all text before that             \$output = substr(\$output, strpos(\$output, "\n") + 1);           }           // Close file and return         fclose(\$f);         return trim(\$output);       } function isPrime( \$num )  {      for( \$i = 2; \$i*\$i <= \$num; \$i++ )          if( !fmod(\$num,\$i) )              return FALSE;      return TRUE;  }  \$logfile = 'prim_save.log'; \$lastline = explode(";", tailCustom(\$logfile)); \$begin = (\$lastline +1); \$lastprime = \$lastline; \$end = 999999999999999999999999999999999999;  \$fp = fopen(\$logfile, 'a'); //Lineformat    \$i.';'.\$difference.';'."\n" for(\$i = \$begin; \$i<\$end; \$i++)  {      if(isPrime(\$i) == TRUE)      {          \$difference = \$i - \$lastprime;         fputs(\$fp,\$i.';'.\$difference.';'."\n");         \$lastprime = \$i;     }  } fclose(\$fp); ?> ```
2014-01-28 13:23:16
http://php5.kiev.ua/manual/ru/function.fmod.html
``` The behaviour of this function seems to have changed over time. <?php echo fmod(3,5);  // php 5.3.2 outputs -2 // php 5.3.8 outputs 3 echo fmod(2,5);  // php 5.3.2 outputs 2 // php 5.3.8 outputs 2 ?> - Timo ```
2014-10-27 15:40:17
http://php5.kiev.ua/manual/ru/function.fmod.html
``` Note that fmod does not behave like a similar function written in PHP itself does due to the lack of fixing floating point representation errors. Have a look at this: <?php var_dump(10 / (10 / 3) === 3.0); // bool(true) var_dump(fmod(10, 10 / 3)); // float(3.3333333333333) var_dump(fmod(10, 10 / 3) < 10 / 3); // bool(true) ?> Internally there is no way of exactly representing the result of 10 / 3, so it will always be a bit above or below the actual result. In this case, the example proves it being a bit above the actual result. PHP seems quite good at auto-fixing floating point representation errors so they behave like the user would expect it. That's why the first line yields true, although the result is slightly below 3 (like 2.9999999999[something]). I failed to trick PHP into rounding or cropping the result to 2. However, fmod seems to not apply these fixes during calculations. From 10 / 3 it gets a value slightly below 3, floors it to 2 and returns 10 - 2 * 10 / 3, which is slightly less than the actual result of 10 / 3, but looks like 10 / 3 (third line). Unfortunately, this is not the expected result. See other notes for high quality fixes. ```
2017-01-04 12:11:09
http://php5.kiev.ua/manual/ru/function.fmod.html
``` WARNING: Due to how floating point numbers work, fmod() and any simple alternatives are problematic when there is either a massive orders of magnitude different between the input \$x and \$y, or the input and output values. If you need to work with large numbers or arbitrary precision, it is best to work with something like BC Math or GMP. When working around fmod()'s problems, remember that floor() always goes towards -INF, not 0. This causes a commonly proposed fmod() alternative to only work with positive numbers: <?php  function fmod_positive_only(\$x, \$y) {     return \$x - floor(\$x/\$y) * \$y; } ?> Given these simplistic input values: fmod_positive_only(-5, 3) = 1 (wrong) -5 % 3 = -2 (correct) Correctly removing the decimal part of the quotient can be achieved with either casting to an int (always goes towards zero) or dynamically choosing ceil() or floor(). Dynamically choosing floor or ceil in an attempt to keep precision is overkill. If your \$x and \$y values are so different that it suffers from an overflow problem when casting, it was probably going to have precision problems anyway (see warnings below). <?php  function fmod_overkill(\$x, \$y) {     if (!\$y) { return NAN; }     \$q = \$x / \$y;     \$f = (\$q < 0 ? 'ceil' : 'floor');     return \$x - \$f(\$q) * \$y; } ?> This is the "best" alternative for fmod() when given "normal" numbers. <?php function fmod_alt(\$x, \$y) {     if (!\$y) { return NAN; }     return floatval(\$x - intval(\$x / \$y) * \$y); } ?> WARNING: Even when you get a non-zero response, know your input numbers and when fmod() can go wrong. For large values or depending on your input variable types, float still may not contain enough precision to get back the correct answer. Here are a few problems with fmod() and their alternatives. PHP_INT_MAX = 9223372036854775807 fmod(PHP_INT_MAX, 2) = 0 (wrong) fmod_alt(PHP_INT_MAX, 2) = 0 (wrong) PHP_INT_MAX % 2 = 1 (correct) fmod(PHP_INT_MAX, PHP_INT_MAX - 1) = 0 (wrong) fmod_alt(PHP_INT_MAX, PHP_INT_MAX - 1) = 1 (correct) fmod_alt(PHP_INT_MAX, PHP_INT_MAX - 1.0) = 0 (wrong) PHP_INT_MAX % (PHP_INT_MAX - 1) = 1 (correct) PHP_INT_MAX % (PHP_INT_MAX - 1.0) = 9223372036854775807 (wrong) fmod(PHP_INT_MAX, 131) =  98 (wrong) fmod_alt(PHP_INT_MAX, 131) = 359 (wrong) fmod_positive_only(PHP_INT_MAX, 131) = 0 (wrong) PHP_INT_MAX % 131 = 97 (correct) ```
2018-05-30 18:26:03
http://php5.kiev.ua/manual/ru/function.fmod.html
``` Do not relly on that function, for example: \$a = "7.191" \$b =  "2.397000" if(fmod(floatval(\$a), floatval(\$b)) === 0.0) { .. //is false, becouse //float(4.4408920985006E-16) != 0.0 ```
2018-06-20 14:43:03
http://php5.kiev.ua/manual/ru/function.fmod.html

Поддержать сайт на родительском проекте КГБ