我需要传递一个整数常量作为泛型参数。例如,这里是一个使用非标准浮点数(float16)的代码(代码取自githab并稍加修改):
const
ES = 5; // exponent size (bits)
MS = 10; // mantissa size (bits)
// plus sign (1 bit)
ESMS = ES + MS;
function FloatXXToSingle(const _in: cardinal): Single;
var
t1, t2, t3: cardinal;
begin
t1 := _in and (Cardinal(1 shl ESMS) - 1); // Non-sign bits
t2 := _in and (1 shl ESMS); // Sign bit
t3 := _in and ((1 shl ES - 1) shl MS); // Exponent
t1 := t1 shl (23 - MS); // Align mantissa on MSB
t2 := t2 shl (31 - ESMS); // Shift sign bit into position
t1 := t1 + cardinal((127-(1 shl (ES-1)-1)) shl 23); // Adjust bias
if t3 = 0 then // Denormals-as-zero
t1 := 0;
t1 := t1 or t2; // Re-insert sign bit
pCardinal(@Result)^ := t1;
end;
我想在它的基础上创建一个泛型,这样我就可以自己设置指数和尾数的位数。 现在我做这样的事情:
type
TFloat<TES, TMS> = class
const ES = sizeof(TES);
const MS = sizeof(TMS);
const ESMS = ES + MS;
class function ToSingle(const _in: cardinal): Single;
end;
class function TFloat<TES, TMS>.ToSingle(const _in: cardinal): Single;
var
t1, t2, t3: cardinal;
begin
t1 := _in and (Cardinal(1 shl ESMS) - 1); // Non-sign bits
t2 := _in and (1 shl ESMS); // Sign bit
t3 := _in and ((1 shl ES - 1) shl MS); // Exponent
t1 := t1 shl (23 - MS); // Align mantissa on MSB
t2 := t2 shl (31 - ESMS); // Shift sign bit into position
t1 := t1 + cardinal((127-(1 shl (ES-1)-1)) shl 23); // Adjust bias
if t3 = 0 then // Denormals-as-zero
t1 := 0;
t1 := t1 or t2; // Re-insert sign bit
pCardinal(@Result)^ := t1;
end;
但是要使用它,我必须写这样的东西:
type
TMyFloat = TFloat<packed record a:Integer; b:Byte; end, packed record a: Extended; end>;
begin
writeln(TMyFloat.ToSingle($1234));
end.
但这种方法并不优雅。也许有一种方法可以直接将两个数字传递给泛型:指数的大小和尾数?