WARNING!
Manipulating memory incorrectly can cause memory exceptions and therefore crashes.
Be prepared for this. Play with 15!: in a J session separate from all your other work, and save your snippets regularly (so if you mistype one, you won't lose all your effort).
memory manipulation
On a 32-bit, Intel x86 (implementing the IEEE 754 floating point spec), little-endian (MS Windows) platform:
3 : '%y [ (128{a.) 15!:2 ] 39 1 2 ,~ 1 { 15!:1 ] 0 2 4 ,~ 15!:6 {. ;:''y'' ([ (0 0 $ 1!:2&2)@:%) y' {. 0 2.5
_
__ The foregoing basically demonstrates how to manipulate the bytes underlying a name (in this case, it converts y from a normal (floating point) 0 to a "negative zero".
The mechanism is memory manipulation. It could be written less obscurely
require 'dll'
fw =: {.@:;:
mm =: verb define
Z =. %y
ptr2y =. symget fw 'y'
NB. For some reason, need to call 1 { (read 2 ints starting at zero)
NB. instead of (read one int starting at 1).
ptr2y_hdr =. 1 { memr ptr2y, 0 2, JINT NB.! sizeof(int) == sizeof(ptr)
NB. The 128{a. means 16b80 ("0x80") which turns on the sign
NB. bit but leaves the other bits zero (for the IEEE spec).
NB. The 39 here is _very_ sensitive to platform
(128 { a.) memw ptr2y_hdr, 39 1, JCHAR
Z , %y
)
FP_zero =: {. 0 2.5 NB. 2.5 to force promotion to FP
mm FP_zero
_ __
to do
Would be nice to document J internal structures as completely as possible (for all nameclasses / parts of speech etc). Reading open 'jmf' is a good start.
see also
The "zero" thread on the Forums.
(I don't know why I wrote 4 ,~ 2 ,~ 0 ,~ and 2 ,~ 1 ,~ 39 ,~ instead of the terser 0 2 4 ,~ and 39 1 2 ,~ ).
