What do you do when number is too big to process?

ygreq's icon

Hi everyone,

I was trying to combine some numbers (glue them together) and I realized there is a limitation.

if i glue 20101130 and 114422, expecting to have 20101130114422 I only get 2147483647.

Max Patch
Copy patch and select New From Clipboard in Max.

I am guessing it is related to the limitation of integers. Is this it? And can I overcome this?

Peter Castine's icon

Integers are represented as 32-bit numbers, which limits their range from -2,147,483,648 to 2,147,483,647.

You might want to try a [sprintf symout %d%d] to paste your yearmonthday and hoursminutesseconds to a single symbol (string).

Note that you won't be able to do arithmetic or order comparisons with symbols. If you need comparisons, you'll have to stick to keeping the components in lists and patch a small abstraction to handle the logic.

ygreq's icon

Thanks Peter,

I wanted to do calculations with it so string is out of the question in this case.
I wanted to use them as a index in a coll. And to use the "goto" message to go to the specific date and hour in the coll. I see that the 2 numbers can be used as 1 symbol to act as an index so I'll use them as such. And calculate by transforming the symbol to numbers whenever I need to compute something and back again to a symbol.

Floating Point's icon
Max Patch
Copy patch and select New From Clipboard in Max.

Or you can convert gregorian date to julian and use the unique julian date as an index:

Peter Castine's icon

There are a number of ways to handle what you want.

Terry's suggestion is one (although he's abusing the terms "Gregorian" and "Julian", but don't get hung up on that).

The irony is that when the [date] object asks the OS for the current date and time, the OS is providing it with a single number that you could have used as a time stamp. But [date] goes and unravels that number into 6 components (and puts day and month into the wrong order in the process:)

There is probably a custom object you can find at MaxObjects.com that will directly provide a 32-bit time stamp based on the date/time representation used by the OS.

If you're rebuilding your coll every time your patch is used, it might be easier just to use [date]'s third outlet, which will give you a unique number on every bang. That won't work, however, if you write your coll to disk and want to reopen it at another date and merge in new timestamps and you need to keep them all nicely ordered.

If you want to have an easily decipherable timestamp number, you could consider trimming the year down to the last two digits and dropping the seconds (how often do you need the timestamps?). You could then concatenate the digits to yyMMddhhmm (MM for month/mm for minutes) which will fit nicely in a 32-bit number and would keep you going until 31 Dec 2021.

There are lots of other approaches. Hard to know which one will work best for you.

ygreq's icon

Ahh! This is wonderful! Thank you, Terry!

And I was also searching for a native object to show the date. And here it is. [date] :P

Floating Point's icon

glad it's of use-- btw if you get the modulus 7 [% 7] of the julian number you get the day of the week (i think 0 is Monday)
T

johnpitcairn's icon

Not date-related, but on-topic for the subject:

I have a project under consideration where I really do need to work with 64-bit unsigned integers, but the processing on those can be handled by custom externals. I've been thinking of outputting those as messages of two 32-bit signed integers, storing them where necessary under the same index in an abstraction of funbuff pairs or such. A bit like handling 14-bit MIDI as two MSB/LSB messages. Feh.

Wouldn't it be nice if we native 64-bit int/float support in Max?

Roman Thilenius's icon

not if someone needs 256 bits of precision, then 53 will still not be enough.

but who needs that?

i see no reason to treat a value, which contains the information for
year:month:week:hous:minute:second:millisecond in a decimal
number of 72 bits.
you can encode such an int by transforming it into two values, one
for month and one for milliseonds, these tow numbers will fit into
a 24 bit int, and if you now want to substract 17% or add 3 years
you just do that to both values.

ygreq's icon

hey Peter,

I just read your post. I think we replied in the same time, as I didn't notice your post until now.

I am trying to create a database for some sensors I installed in the house (as a personal, side project). I am using the time stamping in the coll for later processing. As I gave up (for now) trying to upload data to pachube.com (I just don't know how to do it from max), I am trying to create a patch to save and visualize sensor use (water consumption, temperature, humidity).

I even found a free example of what a simple software should do (http://www.miloslick.com/EnergyLogger.html). For everyone interested, you should test this! But I want something opensource and obviously in max! :)

Anyway thank you for the very good ideas related to how I can use the output from [date]. I'll see what I can do!

ygreq's icon

Thanks Terry, I'll definitely try to use modulo!

Sorry Roman! I don't follow you!

ygreq's icon

I found out this site where it talks about the Julian day number. http://www.hermetic.ch/cal_stud/jdn.htm

And there is says: "Thus the Julian day number of -4712-01-01 is 0. The Julian day number of 1996-03-31 CE (Common Era) is 2,450,174 — meaning that on 1996-03-31 CE 2,450,174 days had elapsed since -4712-01-01 JC."

But from my calculations, -4712-01-01 is not 0, but 38 in Terry's patch. The other calculation, 1996-03-31 CE (Common Era) is 2,450,174 seems to be alright.

Still I am guessing this will not affect my future calculations. :)

Floating Point's icon

this probably relates to arcane discrepancies with various definitions of how the julian calendar is described-- it may or may not be to do with 'leap days' which might occur every hundred years or so and subsequently accumulate over the 6 or 7 thousand year period or something else of a similar ilk (either that or my patch is wrong!)-- for the purposes of an individual's lifetime in the 21st century it wont matter. I've used this method to control a patch which can schedule the playing of midi files up to ten years in advance, for the past few years (a permanent public art installation), and it has worked fine. I got the formula off the internet and admittedly didn't test it against 'year zero'
T

ygreq's icon

:) Thank you for the kind explanation!

Peter Castine's icon

What Roman was basically saying (if I understand him correctly:) is that storing year/month/day/hours/minutes/seconds as a 14 digit decimal number is inefficient in terms of information theory. The decimal representation requires 48 bits whereas an optimal representation only requires 35 bits (including all years from 1 to 10,000 CE). You can squeeze the data into a 32 bit word if you limit the years to a period of just over a century. Classic Mac OS, for example did this by only representing years from 1904 to 2040; Unix used a similar technique.

Nowadays, OSs use 64 bits and support dates over periods of hundreds of millennia with sub-microsecond accuracy. You can do a lot with 64-bits.

ztutz's icon

FWIW and only slightly off topic, I've successfully done pieces built with very large numbers, such as transcendentals to thousands of digits, and have had success using various open-source libraries and/or computer algebra programs. apfloat has a java version, for example. If you are interested in packaging as an external, there are also a number of good arbitrary-precision libraries available for C++. In my experience, you wind up being limited by the size of the character arrays that you can pass around, unless you are consuming digits in chunks. (But you can always fall back to file I/O, or to calculating on the fly!)

Native 64-bit would be nice because of its implications for the DSP processing chain, if nothing else! Big job, I suspect - not a trivial change to a venerable program.

ygreq's icon

Externals and the like is not something I can delve into, unfortunately!

From my point of view (using it as a [coll] index, I mean), I just used the symbol method described in my second post here, and used Terry's method whenever I had to go to a previous date (otherwise it would've been hell to extract days from the current date) in the [coll].

I understood a lot of new things from this post so I thank all of you once more!

All the best,
ygr

Roman Thilenius's icon

what i was basically saying (if i understand myself correctly) is that he was originally
asking for a way how to process numbers like 20101130114422 and how to use them
as an index in a coll.

what i would suggest is not to process such numbers and not to use such
indices in coll, because there is no useful process you could do to an artificial
integerama-banana number like that because it contains three different
systems: dezimal, 12 months per year, and an anormal number of days per
month.

what do you want to do with 20101130114422?

do you want to add 00013000000000 in order to get the milisecond in exactly
13 months? that wont work.

you need to split it into year, month and day-milliseconds anyway when you
want to process this term, so you can also store it like that.

-year 110

ygreq's icon

Like I said I just needed it for storing! But that's fixed now. From a numerical point of view, considering that year 2010 is always after year 2009 and month 09 is always before month 10, and day 13 is always 2 days before 15, and hour 18 before 20, and so on and so forth..

..a number like 20100913180000 will always be before 20091015200000!

That's the logic! Too bad they don't compute! But it's ok!