Re[5]: с ассемблера на С
От: Programador  
Дата: 12.06.07 12:09
Оценка: 12 (1) +1
Здравствуйте, Cruser, Вы писали:


GN>>Замечания к С коду (не принимая во внимания исходный asm)

GN>>
GN>>double Rand_0_1()
GN>>{  __int64 f=randShift*__int64(0x8088405);
GN>>   f+=0x00010000LL;
GN>>   f&=0xffff0000LL;  // результат будет всегда помещаться в 32 бита, смысла использовать 64х битный тип нет
GN>>   randShift=f>>32;  // здесь всегда 0
GN>>   return float(randShift)*revMaxLong;
GN>>}

GN>>Исходя только из этого видно, что код некорректен.

C> Результат тут не причём, тут затрагиваются просто первые 32 бита из 64, а потом они почему-то сдвигаются вправо...


В общем бессмычленно обсуждать ошибки. Возможно Вы говорите тоже что и gear nuke. Первое — я увидел EDX и решил почемуто что старшие нужны, взятие по мске написал просто для наглядности, оно то и не нужно, Второе — както непривычно писать 0xffffffff00000000LL.

У gear nuke тут действительно ошибка.
unsigned int randShift;
long double Rand_0_1()
{ 
  randShift = randShift * 134775813 + 1; // тип муля по барабану - хош MUL хош IMUL на младшие не влияет
  return randShift*((1.0/0x10000) / 0x10000); // здесь randShift безззнаковое
}


В сопроцессор загружаются 64 бита. Дело в том что FILD принимает знаковое, а
        PUSH    0
        PUSH    EDX

расширяет EDX нулями и загругка длинная-длинная FILD qword ptr [ESP].
Re[3]: с ассемблера на С
От: Programador  
Дата: 06.06.07 15:45
Оценка: 1 (1) -1
Здравствуйте, Programador, Вы писали:

P>>
P>>double Rand_0_1()
P>>{  __int64 f=randShift*__int64(0x8088405);
P>>   f+=0x00010000LL;
P>>   f&=0xffff0000LL;
P>>   randShift=f>>32;
P>>   return float(randShift)*revMaxLong;
P>>}
P>>
Re: с ассемблера на С
От: Programador  
Дата: 07.06.07 20:04
Оценка: :)
Здравствуйте, gimalay, Вы писали:
G>Буду крайне признателен.

А спасибо где?
с ассемблера на С
От: gimalay  
Дата: 06.06.07 13:37
Оценка:
Может кто нибуть подсказать как перевести сей код на С. Без использования ассемблера.
Необходимо получить туже последовательность псевдослучайных чисел.


function Rand_0_1 : extended;
const revMaxLong: double = ((1.0/$10000) / $10000);  // 2^-32

asm
        IMUL    EDX,randShift,08088405H
        INC     EDX
        MOV     randShift,EDX
        FLD     revMaxLong
        PUSH    0
        PUSH    EDX
        FILD    qword ptr [ESP]
        ADD     ESP,8
        FMULP  ST(1), ST(0)
end;


Буду крайне признателен.
Re: с ассемблера на С
От: Programador  
Дата: 06.06.07 15:35
Оценка:
Здравствуйте, gimalay, Вы писали:

G>Может кто нибуть подсказать как перевести сей код на С. Без использования ассемблера.

G>Необходимо получить туже последовательность псевдослучайных чисел.


G>
G>function Rand_0_1 : extended;
G>const revMaxLong: double = ((1.0/$10000) / $10000);  // 2^-32

G>asm
G>        IMUL    EDX,randShift,08088405H
G>        INC     EDX
G>        MOV     randShift,EDX
G>        FLD     revMaxLong
G>        PUSH    0
G>        PUSH    EDX
G>        FILD    qword ptr [ESP]
G>        ADD     ESP,8
G>        FMULP  ST(1), ST(0)
G>end;
G>


G>Буду крайне признателен.



double Rand_0_1()
{  __int64 f=randShift*__int64(randShift);
   f+=0x00010000LL;
   f&=0xffff0000LL;
   randShift=f>>32;
   return float(f)*revMaxLong;
}
Re[2]: с ассемблера на С
От: Programador  
Дата: 06.06.07 15:37
Оценка:
P>
P>double Rand_0_1()
P>{  __int64 f=randShift*__int64(0x8088405);
P>   f+=0x00010000LL;
P>   f&=0xffff0000LL;
P>   randShift=f>>32;
P>   return float(f)*revMaxLong;
P>}
P>
Re: с ассемблера на С
От: gear nuke  
Дата: 09.06.07 00:42
Оценка:
Здравствуйте, gimalay,

int randShift;

long double Rand_0_1()
{
  static const double revMaxLong = ((1.0/0x10000) / 0x10000);  // 2^-32
  randShift = randShift * 134775813 + 1;
  return revMaxLong * randShift;
}


Вот только у MSVC long double не 10, а 8 байт
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[2]: с ассемблера на С
От: Programador  
Дата: 09.06.07 19:32
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, gimalay,

чет давненько 86-м не баловался, подзабыл
Re[3]: с ассемблера на С
От: gear nuke  
Дата: 10.06.07 04:22
Оценка:
Здравствуйте, Programador,

P>чет давненько 86-м не баловался


Замечания к С коду (не принимая во внимания исходный asm)
double Rand_0_1()
{  __int64 f=randShift*__int64(0x8088405);
   f+=0x00010000LL;
   f&=0xffff0000LL;  // результат будет всегда помещаться в 32 бита, смысла использовать 64х битный тип нет
   randShift=f>>32;  // здесь всегда 0
   return float(randShift)*revMaxLong;
}

Исходя только из этого видно, что код некорректен.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[4]: с ассемблера на С
От: Cruser Украина  
Дата: 12.06.07 09:35
Оценка:
GN>Замечания к С коду (не принимая во внимания исходный asm)
GN>
GN>double Rand_0_1()
GN>{  __int64 f=randShift*__int64(0x8088405);
GN>   f+=0x00010000LL;
GN>   f&=0xffff0000LL;  // результат будет всегда помещаться в 32 бита, смысла использовать 64х битный тип нет
GN>   randShift=f>>32;  // здесь всегда 0
GN>   return float(randShift)*revMaxLong;
GN>}

GN>Исходя только из этого видно, что код некорректен.

Результат тут не причём, тут затрагиваются просто первые 32 бита из 64, а потом они почему-то сдвигаются вправо...
Re[5]: с ассемблера на С
От: gear nuke  
Дата: 12.06.07 12:11
Оценка:
Здравствуйте, Cruser, Вы писали:

C> Результат тут не причём, тут затрагиваются просто первые 32 бита из 64


Ну, если начнём касаться исходного ассемблера — то команда
IMUL    EDX,randShift,08088405H

это 32х битное умножение. Так что минус лучше себе поставь

C>а потом они почему-то сдвигаются вправо...


И в результате функции всегда 0
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.