Groveler and HUGE_VAL

Stelian Ionescu sionescu at cddr.org
Fri Apr 26 02:23:00 UTC 2013


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

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
URL: <https://mailman.common-lisp.net/pipermail/cffi-devel/attachments/20130426/8568239d/attachment.sig>


More information about the cffi-devel mailing list