On Thu, 2013-04-25 at 16:31 -0600, Zach wrote: > I am trying to grovel the value of HUGE_VAL from math.h. This: > (constant (huge-val "HUGE_VAL") :type double-float) > doesn't work, presumably because HUGE_VAL isn't a proper float on my > system (but rather some special positive infinity double float). I > get this error: > > The value NLOPT::INF is not of type REAL.
> I need to use HUGE_VAL in the arguments in my NLOpt bindings (hence > the package name in NLOPT::INF, though I don't think I even typed INF > into the system). I believe that I can't use, say, > most-positive-double-float, as there is special behavior when the > value HUGE_VAL is used, i.e. it isn't just a large number. > Interestingly, I can grovel HUGE_VAL as an integer with value > 18446744073709551615 which, presumably, if I used the ieee-floats > system: > > (ieee-floats:decode-float64 18446744073709551615) == HUGE_VAL > > However, I'm not sure of that and that form naturally produces an > overflow error. This is a value that cannot actually be represented > as a float, after all. Anyway, I'm not sure that this helps me as I > have to pass it to a function that expects a double (actually I pass > it as an element in an array of doubles that gets passed to the > function): > nlopt_result nlopt_set_lower_bounds(nlopt_opt opt, const double* lb); > So, I think I need to hold the sizeof(double) bytes in memory > (whatever the value of HUGE_VAL is) so that I can write it out to an > array later. This is doable, but I am having trouble figuring out the > syntax to have the groveler automate the task of getting those > sizeof(double) bytes in the first place. > Is there a way to deal with this? Even better, is there a way that > CFFI makes this much simpler so I can just pass define whatever holds > HUGE_VAL as an opaque object that can be used as a double? Even > better yet, the value of HUGE_VAL provided by CFFI already and I am > just not seeing it? > Remember that CFFI is untyped, so every (de)reference is an implicit cast. As long as you're careful about the type sizes, you can do something like this: (with-foreign-object (huge :uint64) (setf (mem-ref huge :uint64) (expt 2 63)) (mem-ref huge :double)) When defining the binding to nlopt_set_lower_bounds, the second argument will be a (generic) pointer and you can pass a pointer to anything. (constant (+huge-val+ "HUGE_VAL") :type integer) then (with-foreign-object (huge-ptr :uint64) (setf (mem-ref huge-ptr :uint64) +huge-val+) (nlopt-set-lower-bound opts huge-ptr)) -- Stelian Ionescu a.k.a. fe[nl]ix Quidquid latine dictum sit, altum videtur. http://common-lisp.net/project/iolib
signature.asc
Description: This is a digitally signed message part