Maybe? I think (<.) is not properly specified for large floats. The dictionary seems to imply that the result of (<.a) is the largest integer b such that (b<:a) using tolerant comparison. But that's certainly not the correct behavior of floor: shown below, for (a=2^45), we would have to set (<.a) equal to (a+2)!
]b =. <.2^45 35184372088832 (b+2) <: 2^45 1 b =!.0 ]2^45 1 In fact, the J source uses the C code (x=jfloor(0.5+v), x-TGT(x,v)) to compute tolerant floor for integer ranges. jfloor is a not-tolerant floor which accepts and returns a float, and TGT(x,v) is J's tolerant (x>v). This guarantees that the result of (<.a) is no more than one away from (a). A proper definition from this code would be: If y is tolerantly equal to an integer (including integers expressed in floating point), (<.y) is the integer closest to y. Otherwise, (<.y) is the largest integer less than y. The result of (<.) is of integer type if and only if it is between 2^-63 and 2^63-1, inclusive. So under this (reasonable, in my opinion) interpretation of (<.), J is correct. In any case, I think it's important exactly because of confusion like this to have a utility that performs conversions with very precisely specified behavior. Marshall On Sat, Feb 06, 2016 at 08:22:37PM -0500, Raul Miller wrote: > Yeah, it's a bug. But I'm pretty sure it's a bug in the interpreter, > which your code is simply reporting on. > > -- > Raul > > > On Sat, Feb 6, 2016 at 7:53 PM, Marshall Lochbaum <[email protected]> > wrote: > > The spec is that if there is a noun of the given type that matches, it > > should be returned. So this is actually a bug, given: > > > > MAX_ptype_ > > 9223372036854775807 > > MAX_ptype_ -: 432.1-~2^63 > > 1 > > > > (Note that (431-~2^63) is exactly the same as (2^63), as one can verify > > with -:!.0). > > > > > > However, converting floats to integers only up to comparison tolerance > > doesn't seem right since it allows us to convert much larger numbers > > to the same value MAX_ptype_ (up to (+/2^63 19)). I considered at one > > point requiring > > > > y -: (3!:0 y) typecast x typecast y > > > > but that doesn't seem to make sense either, as it prevents sending a > > number like (<:2^62), which is close to but not exactly equal to a > > float, to that float: > > > > (, 4 typecast 8 typecast ]) <:2<.@^62 > > 4611686018427387903 4611686018427387904 > > (-: 4 typecast 8 typecast ]) <:2<.@^62 > > 0 > > > > I will make typecast follow the current spec (with relatively liberal > > float->int conversion). However, it might make sense to also have a > > strict conversion function for numbers that obeys the additional rule, > > and only converts an int if there's a float that uniquely represents it. > > > > Marshall > > > > On Sat, Feb 06, 2016 at 06:59:06PM -0500, Raul Miller wrote: > >> Hmm... I guess throwing an error works for cases like > >> 4 typecast (2^63)-432.1 > >> > >> It would be nice if that particular integer could be converted, but > >> mostly no one should care. > >> > >> Anyways, nice piece of work (though I'll have to admit I did not > >> exercise it thoroughly - I am only assuming it works well for many > >> cases). > >> > >> Thanks, > >> > >> -- > >> Raul > >> > >> > >> On Sat, Feb 6, 2016 at 4:38 PM, Marshall Lochbaum <[email protected]> > >> wrote: > >> > Based on the recent discussions about integers and floats, I decided to > >> > make a general tool to convert between various J types. It's hosted > >> > here: > >> > > >> > https://github.com/mlochbaum/JScripts/blob/master/Misc/typecast.ijs > >> > > >> > The script defines typecast, a verb to convert between types while > >> > maintaining J equivalence (-:), and numcast, a verb which converts > >> > between numeric types and guarantees no errors. Both of these operations > >> > are quite error-prone, so it's good to have a reference with (lightly, > >> > at the moment) tested verbs to perform them. > >> > > >> > My goal is to eventually have a glossary of ways to convert between > >> > types. I will probably make typecast suggest alternative conversion > >> > methods if it fails on a particular argument. So I'm curious if anyone > >> > knows of interesting and useful ways to convert types. The ones I know > >> > of are: > >> > > >> > - Conversions (3!:x) from numbers to bytes > >> > - (0&~:) to convert numbers to booleans > >> > - (mod 2^64) conversion from exact to 64-bit integer > >> > - Representations (5!:x) from nouns (or other parts of speech) to > >> > strings or boxes. > >> > - Gerund representation for a verb > >> > - The sneaky trick which boxes a part of speech directly > >> > > >> > Any others? > >> > > >> > Marshall > >> > ---------------------------------------------------------------------- > >> > For information about J forums see http://www.jsoftware.com/forums.htm > >> ---------------------------------------------------------------------- > >> For information about J forums see http://www.jsoftware.com/forums.htm > > ---------------------------------------------------------------------- > > For information about J forums see http://www.jsoftware.com/forums.htm > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
