void printf (string ftm, ...) = #0; float snafu (float a, float b) { float c = a % b; return c; } int imodulo (int a, int b) { return a %% b; } float fmodulo (float a, float b) { return a %% b; } double dmodulo (double a, double b) { return a %% b; } #pragma traditional float foo (float a, float b) { float c = a % b; return c; } #pragma advanced float bar (float a, float b) { float c; b &= b; a &= a; c = a - ((a / b) & -1) * b; return c; } #pragma traditional float baz (float a, float b) { float c = (a + b) % (a - b); return c; } #pragma advanced @overload int test (string name, string op, int (func)(int a, int b), int a, int b, int c) { int ret; ret = func (a, b); if (ret != c) { if (func == baz) printf ("%s: (%d + %d) %% (%d - %d): %d != %d\n", name, a, b, a, b, ret, c); else printf ("%s: %d %s %d: %d != %d\n", name, a, op, b, ret, c); return 1; } return 0; } @overload int test (string name, string op, float (func)(float a, float b), float a, float b, float c) { float ret; ret = func (a, b); if (ret != c) { if (func == baz) printf ("%s: (%g + %g) %% (%g - %g): %g != %g\n", name, a, b, a, b, ret, c); else printf ("%s: %g %s %g: %g != %g\n", name, a, op, b, ret, c); return 1; } return 0; } @overload int test (string name, string op, double (func)(double a, double b), double a, double b, double c) { double ret; ret = func (a, b); if (ret != c) { if (func == baz) printf ("%s: (%g + %g) %% (%g - %g): %g != %g\n", name, a, b, a, b, ret, c); else printf ("%s: %g %s %g: %g != %g\n", name, a, op, b, ret, c); return 1; } return 0; } float main (void) { float res = 0; res |= test ("foo", "%", foo, 5, 3, 2); res |= test ("bar", "%", bar, 5, 3, 2); res |= test ("baz", "%", baz, 5, 3, 0); res |= test ("snafu", "%", snafu, 5, 3, 2); res |= test ("foo", "%", foo, -5, 3, -2); res |= test ("bar", "%", bar, -5, 3, -2); res |= test ("baz", "%", baz, -5, 3, -2); res |= test ("snafu", "%", snafu, -5, 3, -2); res |= test ("foo", "%", foo, 5, -3, 2); res |= test ("bar", "%", bar, 5, -3, 2); res |= test ("baz", "%", baz, 5, -3, 2); res |= test ("snafu", "%", snafu, 5, -3, 2); res |= test ("foo", "%", foo, -5, -3, -2); res |= test ("bar", "%", bar, -5, -3, -2); res |= test ("baz", "%", baz, -5, -3, 0); res |= test ("snafu", "%", snafu, -5, -3, -2); res |= test ("foo", "%", foo, 5, 3.5, 1.5); res |= test ("foo", "%", foo, -5, 3.5, -1.5); res |= test ("snafu", "%", snafu, 5, 3.5, 1.5); res |= test ("snafu", "%", snafu, -5, 3.5, -1.5); res |= test ("int modulo", "%%", imodulo, 5, 3, 2); res |= test ("int modulo", "%%", imodulo, -5, 3, 1); res |= test ("int modulo", "%%", imodulo, 5, -3, -1); res |= test ("int modulo", "%%", imodulo, -5, -3, -2); res |= test ("int modulo", "%%", imodulo, 6, 3, 0); res |= test ("int modulo", "%%", imodulo, -6, 3, 0); res |= test ("int modulo", "%%", imodulo, 6, -3, 0); res |= test ("int modulo", "%%", imodulo, -6, -3, 0); res |= test ("float modulo", "%%", fmodulo, 5, 3, 2); res |= test ("float modulo", "%%", fmodulo, -5, 3, 1); res |= test ("float modulo", "%%", fmodulo, 5, -3, -1); res |= test ("float modulo", "%%", fmodulo, -5, -3, -2); res |= test ("float modulo", "%%", fmodulo, 6, 3, 0); res |= test ("float modulo", "%%", fmodulo, -6, 3, 0); res |= test ("float modulo", "%%", fmodulo, 6, -3, 0); res |= test ("float modulo", "%%", fmodulo, -6, -3, 0); res |= test ("double modulo", "%%", dmodulo, 5, 3, 2); res |= test ("double modulo", "%%", dmodulo, -5, 3, 1); res |= test ("double modulo", "%%", dmodulo, 5, -3, -1); res |= test ("double modulo", "%%", dmodulo, -5, -3, -2); res |= test ("double modulo", "%%", dmodulo, 6, 3, 0); res |= test ("double modulo", "%%", dmodulo, -6, 3, 0); res |= test ("double modulo", "%%", dmodulo, 6, -3, 0); res |= test ("double modulo", "%%", dmodulo, -6, -3, 0); return res; }