Home » Developing U++ » U++ Developers corner » "better" version of Iscale functions
"better" version of Iscale functions [message #15129] |
Tue, 01 April 2008 23:10 |
mdelfede
Messages: 1307 Registered: September 2007
|
Ultimate Contributor |
|
|
In file 'mathutils.cpp' the Iscale...() functions use some floating point math, when assembly is unavailable OR when it's not compatible with intel syntax (I.E. GCC and MinGW).
That makes it slow and not showing divide-by-0 errors when third argument is 0.
So, here an (IMHO) better version of such functions :
#include "Core.h"
// iscale: computes x * y / z.
#ifdef flagGCC
#define __USE_64BIT_MATH__
#endif
NAMESPACE_UPP
int iscale(int x, int y, int z)
{
#ifdef __NOASSEMBLY__
#ifndef __USE_64BIT_MATH__
return int(x * (double)y / z);
#else
int64_t res = x;
res *= y;
res /= z;
return (int)res;
#endif
#else
__asm
{
mov eax, [x]
imul [y]
idiv [z]
}
#endif
}
// iscalefloor: computes x * y / z, rounded towards -infty.
int iscalefloor(int x, int y, int z)
{
#ifdef __NOASSEMBLY__
#ifndef __USE_64BIT_MATH__
return (int)ffloor(x * (double)y / z);
#else
int64_t res = x;
int64_t mulres = res * y;
res = mulres / z;
if(res * z != mulres)
res--;
return (int)res;
#endif
#else
__asm
{
mov eax, [x]
imul [y]
idiv [z]
and edx, edx
jge __1
dec eax
__1:
}
#endif
}
// iscaleceil: computes x * y / z, rounded towards +infty.
int iscaleceil(int x, int y, int z)
{
#ifdef __NOASSEMBLY__
#ifndef __USE_64BIT_MATH__
return fceil(x * (double)y / z);
#else
int64_t res = x;
int64_t mulres = res * y;
res = mulres / z;
if(res * z != mulres)
res++;
return (int)res;
#endif
#else
__asm
{
mov eax, [x]
imul [y]
idiv [z]
and edx, edx
jle __1
inc eax
__1:
}
#endif
}
BTW, we could completely drop the assembly code, as-is it's not portable between compilers with greater integer width.
My version is also *not* portable on compilers with 64 bit wide integers, but can be made ok just changing function prototype :
int32_t iscale(int32_t x, int32_t y, int32_t z)
Leaving so to the compiler the integer width check and warnings.
Attached here the patched 'mathutil.cpp' (NO patched function prototype, as it'll require Core.h patch too).
Ciao
Max
-
Attachment: mathutil.cpp
(Size: 4.88KB, Downloaded 302 times)
|
|
|
|
|
"better" version of Iscale functions
By: mdelfede on Tue, 01 April 2008 23:10
|
|
|
Re: "better" version of Iscale functions
By: mirek on Wed, 02 April 2008 15:11
|
|
|
Re: "better" version of Iscale functions
By: mdelfede on Wed, 02 April 2008 16:48
|
|
|
Re: "better" version of Iscale functions
By: mirek on Sun, 06 April 2008 04:47
|
|
|
Re: "better" version of Iscale functions
By: mdelfede on Sun, 06 April 2008 19:36
|
|
|
Re: "better" version of Iscale functions
By: mdelfede on Sun, 06 April 2008 20:05
|
|
|
Re: "better" version of Iscale functions
By: mdelfede on Sun, 06 April 2008 20:14
|
|
|
Re: "better" version of Iscale functions
By: mirek on Thu, 10 April 2008 02:44
|
|
|
Re: "better" version of Iscale functions
By: mirek on Thu, 10 April 2008 02:46
|
|
|
Re: "better" version of Iscale functions
By: mdelfede on Thu, 10 April 2008 15:07
|
|
|
Re: "better" version of Iscale functions
By: mirek on Thu, 10 April 2008 18:01
|
|
|
Re: "better" version of Iscale functions
By: mdelfede on Fri, 11 April 2008 09:26
|
|
|
Re: "better" version of Iscale functions
By: mirek on Sun, 06 April 2008 04:51
|
Goto Forum:
Current Time: Wed Jun 12 00:14:53 CEST 2024
Total time taken to generate the page: 0.01930 seconds
|