0

i want to represent a long value (such as System.currentTimeInMillis() ) in a shorter form. and i'm thinking i can use bit manipulation here, but i'm stuck. i'm not really good at bit ops.

if long value is 1388534400000, how can i represent this as a String but in a shorter form in length?

basically i'd like to write two methods, one to encode and one to decode. so that given a shortened value, i'd like to be able to covert it back to original long value and vice versa.

------- UPDATE -----------

my question was very vague and i'm sorry for the confusion. here's my another attempt at better explanation of what i'm trying to achieve. (also i'll try to simplify my question. let's not think about saving space or persisting to DB).

let's say i have a long value which is a timestamp in milliseconds such as 1388534400123 which is a part of longer string that contains other fixed length numeric values such as (for simplicity) 999913885344001238888. in this case, i've padded with 9999 and 8888. now i have this as a String, but i need a shorter representation that does not lose any of original data (e.g., i want 9999, 1388534400123, and 8888). since these are all numbers, i was vaguely thinking i can use bits to shorten the representation. is there any way?

user3590506
  • 171
  • 1
  • 4
  • 16
  • How would you like 1388534400000 to be represented? – BitNinja Jul 09 '14 at 00:49
  • 2
    Divide? What are trying to accomplish, anyway? – Dave Newton Jul 09 '14 at 00:49
  • i'd prefer end result as a String type – user3590506 Jul 09 '14 at 00:50
  • i'm trying to make it shorter in length when i represent it as a String datatype to save space when i persist this info in DB. but be able to preserve the original value – user3590506 Jul 09 '14 at 00:51
  • 1
    So you want to take a number and represent a smaller form of that number using more memory? This is confusing me. – Dave Newton Jul 09 '14 at 00:51
  • 1
    A long takes up less space than a String .. please expand on what you are trying to do. – ErstwhileIII Jul 09 '14 at 00:52
  • How much space do you think you're saving?! Are you running out of space? – Dave Newton Jul 09 '14 at 00:52
  • Why don't you just persist it as a binary representation if you are worried about data size? – Matt Coubrough Jul 09 '14 at 00:52
  • Sounds like premature optimization to me... – John3136 Jul 09 '14 at 00:54
  • this will be part of even longer string so i'm trying to save where i can. plus i'd prefer this string to be reasonably long, and not extremely long. – user3590506 Jul 09 '14 at 00:55
  • By shorter form you mean you are printing something in a log file and you want the long value to occupy less characters? – morgano Jul 09 '14 at 00:56
  • Do you want the string representation to be shorter? Like using a higher base to store the number as a string – Mar Johnson Jul 09 '14 at 00:58
  • 1
    Can you afford to "lose" data: *ie. are there a valid number of significant figures in the long value?* – Matt Coubrough Jul 09 '14 at 01:02
  • sorry for the confusion. yes, whether String or not, i'd like the representation to be shorter in length. that is my end goal here. so in that sense, it's a yes to morgano's question – user3590506 Jul 09 '14 at 01:03
  • It depends on your context, as above posts, long or bigdecimal takes much less space as string does. If you want to compress the space ,it should use some domain specific knowledge. For example ,your number is something like year-month-day-seq1-seq2-seq3, the first step that you can do is to store every seq1-seq2-seq3 in separated table named TBL_YEAR_MONTH_DAY_YOUR_SUFFIX. – Frank ZHENG Jul 09 '14 at 01:03
  • Are you actually dealing with times in milliseconds? Would you prefer to represent the data as HH:MM:SS.sss? – Matt Coubrough Jul 09 '14 at 01:04
  • option 1) convert it to a hex string. option 2) base64 encoding. option 3) Long.toString(value, radix) for up to base 36 encoding (i think). – Brent Worden Jul 09 '14 at 01:41
  • Numbers are *already* binary. I don't really think you understand what you're doing. In base 36, eight chars, assuming they're stored as bytes, is the same size as a long, harder to read, and may actually be longer if transmitted or stored as anything other than 8-bit chars. I find it very difficult to believe this is a useful exercise. – Dave Newton Jul 09 '14 at 02:32

3 Answers3

2

Some ideas:

convert to hexadecimal:

// long to hex
String myStr = Long.toHexString(System.currentTimeMillis());
// hex to long
long myLong= Long.valueOf(myStr, 16);

If you don't really need milliseconds, trim the last digits:

long myNewLong = System.currentTimeMillis() / 1000;
morgano
  • 17,210
  • 10
  • 45
  • 56
  • Good ideas, although I really think the OP needs to clarify *exactly* what data they are trying to alter and *why* for us to be able to help them better. – Matt Coubrough Jul 09 '14 at 01:05
  • @MattCoubrough you're right, actually the OP already clarified what she/he wants in the comments, but yes, it would be better if she/he re-edited the question – morgano Jul 09 '14 at 01:07
  • i've edited my posting. hopefully it makes more sense. thank you for your suggestions – user3590506 Jul 09 '14 at 01:13
2

If I understand right, you want a string that has the information of a long but is shorter than the actual number in decimal format. I suggest then that you use a higher base to represent your number like, hexadecimal for instance.

Your number (1388534400000) is 13 digits long.
In hex would be: 1434B198400 which is 11 digits long.
Using all letters of the alphabet (base 36) it would be: HPVTJ400 which is 8 digits long.

Another way of reducing the size of the number in a string is to decide that you want to only see some of the relevant digits and use scientific notation:

Assume you only care about 6 significant digits then your number would be:
1.38853E12 which is 10 characters long but a lot easier to read than the base 36 number.

Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
Rusty30
  • 171
  • 9
1

since these are all numbers, i was vaguely thinking i can use bits to shorten the representation. is there any way?

This is called run-length encoding, but it won't really help with timestamps since timestamps, on average, won't have may duplicated digits.

i need a shorter representation that does not lose any of original data

Look into varints. Here's an implementation I wrote. The general idea is use 7 bits for data, 1 bit for as a continuation bit. They're expensive if your values are near 2^31-1 and 2^63-1, but can save space if your values tend to be compressed when compared to the range of your type.

One other thing to consider: if you're storing multiple values in different rows, look into delta encoding combined with varints. Your deltas between timestamps might be just seconds and fit in one or two bytes.

David Ehrmann
  • 7,366
  • 2
  • 31
  • 40