"{ Encoding: utf8 }"
"
COPYRIGHT (c) 2014 by Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
"{ Package: 'stx:libbasic2' }"
"{ NameSpace: Smalltalk }"
UnboxedFloatArray variableWordSubclass:#HalfFloatArray
instanceVariableNames:''
classVariableNames:''
poolDictionaries:''
category:'Collections-Arrayed'
!
!HalfFloatArray primitiveFunctions!
%{
typedef unsigned short uint16;
typedef unsigned int uint32;
#if 0
#if defined(__GNUC__) || defined(__CLANG__) || defined(__MINGW__)
inline float
XMConvertHalfToFloat(float16_t Value) {
__m128i V1 = _mm_cvtsi32_si128( (uint32)(Value) );
__m128 V2 = _mm_cvtph_ps( V1 );
return _mm_cvtss_f32( V2 );
}
inline float16_t
XMConvertFloatToHalf(float Value) {
__m128 V1 = _mm_set_ss( Value );
__m128i V2 = _mm_cvtps_ph( V1, 0 );
return (float16_t)( _mm_cvtsi128_si32(V2) );
}
#endif
#endif
//
// convert a halffloat (16-bit float) to a float
//
extern float __STX_halffloat_to_float(float16_t h);
//
// convert a float to a halffloat (16-bit float)
//
extern float16_t __STX_float_to_halffloat(float f32);
%}
! !
!HalfFloatArray class methodsFor:'documentation'!
copyright
"
COPYRIGHT (c) 2014 by Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
!
documentation
"
HalfFloatArrays store half precision (16bit) floats (and nothing else).
HalfFloats were traditionally seldom used, but seem to become more popular
these days, as some 3D graphics accelerators and game engines use them
for very dense and compact storage of texture and vertex data.
Notice, that HalfFloats are not supported as first class objects by the ST/X system;
i.e. outside of a HalfFloatArray, these values are represented as floats
or doubles. When accessing a HalfFloatArray's element via getters/setters,
shortFloat (i.e. single precision 32bit floats) are exchanged.
Be aware that the numeric range of a half-float is very very limited.
[memory requirements:]
OBJ-HEADER + (size * 2)
[See also:]
FloatArray DoubleArray Array
http://www.opengl.org/wiki/Small_Float_Formats
https://en.wikipedia.org/wiki/Half-precision
[author:]
Claus Gittinger
"
! !
!HalfFloatArray class methodsFor:'queries'!
elementByteSize
"for bit-like containers, return the number of bytes stored per element.
Here, 2 is returned"
^ 2
!
epsilon
"return the maximum relative spacing of elements of mySelf
(i.e. the value-delta of the least significant bit)"
^ 2.0 raisedToInteger:(self precision negated).
"
HalfFloatArray epsilon printStringScientific
"
"Created: / 19-07-2019 / 17:20:20 / Claus Gittinger"
!
precision
"answer the precision (the number of bits in the mantissa) of my elements (in bits)
This is an IEEE halffloat, where only the fraction from the normalized mantissa is stored
and so there is a hidden bit and the mantissa is actually represented by 11 binary digits
(although only 10 are needed in the binary representation)"
^ 11
"Created: / 19-07-2019 / 17:20:25 / Claus Gittinger"
! !
!HalfFloatArray methodsFor:'accessing'!
at:index
%{ /* NOCONTEXT */
if (__isSmallInteger(index)) {
int i = __intVal(index)-1;
int n = __wordArraySize(self);
if ((unsigned)i < n) {
float16_t h;
OBJ newFloat;
float f;
h = (float16_t)(__WordArrayInstPtr(self)->s_element[i]);
f = __STX_halffloat_to_float(h);
__qMKSFLOAT(newFloat, f);
RETURN ( newFloat );
}
}
%}.
self primitiveFailed
!
at:index put:aFloat
%{
if (! __isImmutable(self)) {
if (__isSmallInteger(index)) {
int i = __intVal(index)-1;
int n = __wordArraySize(self);
if ((unsigned)i < n) {
float16_t h;
float f;
if (__isFloat(aFloat)) {
f = (float)(__floatVal(aFloat));
} else if (__isShortFloat(aFloat)) {
f = __shortFloatVal(aFloat);
} else if (__isSmallInteger(aFloat)) {
f = (float)(__intVal(aFloat));
} else
goto error;
h = __STX_float_to_halffloat(f);
__WordArrayInstPtr(self)->s_element[i] = h;
RETURN (aFloat);
}
}
}
error: ;
%}.
"/ arrive here only in case of an error
self isImmutable ifTrue:[
self noModificationError
].
self primitiveFailed
"Modified: / 09-06-2019 / 15:32:32 / Claus Gittinger"
! !
!HalfFloatArray methodsFor:'queries'!
defaultElement
^ ShortFloat zero
!
isValidElement:anObject
"return true, if I can hold this kind of object"
^ anObject isNumber
!
numFloats
^ self size
! !
!HalfFloatArray methodsFor:'testing'!
isFloatArray
"return true if the receiver has float elements.
These are Float, Double- and HalfFloat arrays"
^ true
"Created: / 02-03-2019 / 23:14:00 / Claus Gittinger"
! !
!HalfFloatArray class methodsFor:'documentation'!
version
^ '$Header$'
!
version_CVS
^ '$Header$'
! !