[BUG] ¿Qué estoy haciendo mal con la función abs()?

Started by josebita, December 09, 2008, 10:53:44 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

josebita

Hola:
El siguiente código no me da el resultado que esperaba...
[code language="bennu"]Import "mod_math";
Import "mod_say";

Process main()
Begin
  say(abs(2));
End;[/code]Entiendo que abs() devuelve el valor absoluto de un número, ¿verdad?.
Bueno, pues la salida es:
joseba@josebita-laptop:karaoke$ bgdi tonto2
-0.000031

¿Qué me estoy perdiendo?  ???

SplinterGU

Download Lastest BennuGD Release: http://www.bennugd.org/node/2

josebita

Intenta probarlo tú, a ver si es realmente un bug o es que estoy tonto...
Muchas gracias por adelantado.

Prg

copié tu código completamente y me da esto

[code language="bennu"]> Executing: C:\Archivos de programa\ConTEXT\ConExec.exe "C:\devBennu\bin\bgdi.exe" ero

2
> Execution finished.[/code]

2, lo cual es completamente correcto, a menos que sea porque tengo la versión 15c de windows y tú uses otra.
en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)

josebita

Gracias, prg. Yo estoy en la última de linux (wip16, creo).
A ver si tengo un rato para probar en otro linux, pa ver si es que mi ordenador está loco. ¿Alguien más lo ha probado en linux?.

SplinterGU

ahora mismo no puedo probarlo...

A mi me da un numero gigante, pero esta mal de todas formas, quizas sea algo de linux...

Ahora mismo no puedo dedicarle tiempo...

Anotado...

Download Lastest BennuGD Release: http://www.bennugd.org/node/2

josebita

Vaya, seguro que es una tontería. Cuando puedas, entonces.

SplinterGU

ya vi este error, no es tan tonteria...

se trata de usar...

static int math_abs( INSTANCE * my, int * params )
{
    float num = *( float * ) &params[0] ; <<<
    float res = ( num < 0 ) ? -num : num ;
    return *(( int * )&res ) ; <<<
}

creo que animanegra o alguien una vez hablo de esto en el foro de fenix... la cosa es que antes funcionaba bien, supongo que porque antes yo usaba una version de gcc anterior... se que las ultimas versiones de gcc no son la gloria... voy a comparar con alguna version linux de bennu anterior... me intriga saber que ocaciona esto...

igual esto implica cambiar toda funcion que use esta forma, que es muuuuuchoooooooo....


Download Lastest BennuGD Release: http://www.bennugd.org/node/2

SplinterGU

el problema esta en la linea de return, asi que entonces es menos grave, pero no deja de ser grave el asunto... fucking gnu... (este tipo de cosas son las que hacen a uno dudar del soft libre, pero bueno...)

se soluciona con esto

static int math_abs( INSTANCE * my, int * params )
{
    float num = *( float * ) &params[0] ;
    float res = ( num < 0 ) ? -num : num ;
//    return *(( int * )&res ) ;
    int ret;
    memmove (&ret, &res, sizeof(ret));
    return (ret);
}

o usando un union... puf, que molesto... evidentemente es un bug del gcc, puesto que ambas cosas hacen lo mismo, salvo que el casteo no funciona... ya avisa con un warning y supongo que por eso no compila ese codigo... vamos a ver si hay algun flag o algo que solucione este problema y no tenga que tocar cada maldito fuente...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

SplinterGU

#9
parece que el problema se soluciona agregando -fno-strict-aliasing a los flags de compilacion, vamos a verificar...


EDIT:
Solucionado con ese flag de compilacion... fucking gcc 4.x...

EDIT2:

`-fstrict-aliasing'
     Allows the compiler to assume the strictest aliasing rules
     applicable to the language being compiled.  For C (and C++), this
     activates optimizations based on the type of expressions.  In
     particular, an object of one type is assumed never to reside at
     the same address as an object of a different type, unless the
     types are almost the same.  For example, an `unsigned int' can
     alias an `int', but not a `void*' or a `double'.  A character type
     may alias any other type.

     Pay special attention to code like this:
          union a_union {
            int i;
            double d;
          };

          int f() {
            a_union t;
            t.d = 3.0;
            return t.i;
          }
     The practice of reading from a different union member than the one
     most recently written to (called "type-punning") is common.  Even
     with `-fstrict-aliasing', type-punning is allowed, provided the
     memory is accessed through the union type.  So, the code above
     will work as expected.  However, this code might not:
          int f() {
            a_union t;
            int* ip;
            t.d = 3.0;
            ip = &t.i;
            return *ip;
          }

     ...

     Enabled at levels `-O2', `-O3', `-Os'.


EDIT3:
Fucking gcc 3.x && 4.x... :D
yo creo que usaba 2.95 antes... eso es lo que debia pasar que funcionaba...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

josebita

:) Ya dijeron cuando sacaron el gcc 4 que se había vuelto algo pedante con el código....
Gracias por mirarlo.

PS: Sorry por no contestar antes, se me fue la cabeza

SplinterGU

no, perfecto, gracias a vos por el aviso, a mi se me paso... no me di cuenta...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2