0

I have transaction Class like this:

Public class Transaction
{
    public long Id { get; set; }

    public int DId { get; set; }
    public int BId { get; set; }
    public int DocId { get; set; }
    public int OpId { get; set; }

    public string Description { get; set; }
    public DateTime RegDate { get; set; }
}

I wan to generate a Unique long value based on the DId, BId, DocId & OpId. when we Concat all this fields together, I got Decimal value! now How can I have unique long value based on above fields?

Jourmand
  • 888
  • 10
  • 27
  • @User with this code: `string.Concat(DId, BId, DocId, OpId)` – Jourmand Jan 23 '19 at 14:25
  • I don't see how this will work. `int` is 32-bit and `long` is 64-bit. – Martin Jan 23 '19 at 14:27
  • What if you do `long x = DId*3 + BId*5 + DocId*7 + OpId*9`? Isn't that unique enough? – Zohar Peled Jan 23 '19 at 14:28
  • 2,147,483,647 is the int max value. 9,223,372,036,854,775,807 is long max value. – xdtTransform Jan 23 '19 at 14:29
  • 1
    None of that will work, how can you create a _unique_ long value from 4 int values? It's not possible – Martin Jan 23 '19 at 14:29
  • @User `long.Parse(string.Concat(DId, BId, DocId, OpId))` length of DId = 8 length of BId = 5 length of DocId = 7 length of OpId = 4 – Jourmand Jan 23 '19 at 14:30
  • How high do those individual int values get? A long can only hold two ints unless you can guarantee those int values will be lower than the max value. – bcwhims Jan 23 '19 at 14:31
  • 1
    It's too long. 8+5+7+4 = 24.. Long is 20 max. – xdtTransform Jan 23 '19 at 14:33
  • 1
    @bcwhims Each number will have to be a maximum of 16-bits in order for this to work, so a maximum value of 65,536 (unsigned) or 32,768 (signed) per 'int'. – Martin Jan 23 '19 at 14:33
  • @xdtTransform that's rights, my Question is How can have UNIQUE value base on this fields! no so important to use Concat or any other solution, I just wan to have unique value! – Jourmand Jan 23 '19 at 14:37
  • 1
    If this is a database entity, you might want to take a look at [Composite Keys](https://stackoverflow.com/questions/19792295/mapping-composite-keys-using-ef-code-first), which would be the correct approach if any `Transaction` can be uniquely identified by a combination of `{DId, BId, DocId, OpId}`. Let the Database handle this, do not calculate the Primary Id manually! – Georg Patscheider Jan 23 '19 at 14:39
  • Zohar peled solution is 5.1 10^5 it's short enought to be a long – xdtTransform Jan 23 '19 at 14:39
  • @MartinParkin Int32.MaxValue * 9 * 4 = 77,309,411,292 which is way lower than long.MaxValue of 9,223,372,036,854,775,807. And as for uniqueness - it should **probably** be unique enough - and if not, there are larger primary numbers that can be used for this. – Zohar Peled Jan 23 '19 at 14:43
  • Related: https://math.stackexchange.com/questions/202186/generate-unique-number-from-2-different-numbers – Zohar Peled Jan 23 '19 at 14:55
  • If you know you will have fewer than `long.MaxValue` objects of type `Transaction` then you can create a persisted table (database, whatever) that assigns an incrementing `long` to each combination of DId, BId, DocId & OpId as they come in. – NetMage Jan 23 '19 at 23:47
  • Otherwise you will need to know something about the distribution of the components to reduce the bit requirements until the total fits in a `long`. – NetMage Jan 23 '19 at 23:54

1 Answers1

0

Based on this comment that you added:

long.Parse(string.Concat(DId, BId, DocId, OpId)) length of DId = 8 length of BId = 5 length of DocId = 7 length of OpId = 4

And assuming that what you have said means:

length of DId = 8    Value = 0 to 99,999,999 (up to 27 bits)
length of BId = 5    Value = 0 to 99,999     (up to 17 bits)
length of DocId = 7  Value = 0 to 9,999,999  (up to 24 bits)
length of OpId = 4   Value = 0 to 9,999      (up to 14 bits)

You need a total of 82-bits to guarantee that a unique value can be generated from the four source values.

That is too long to be stored in a long, which has a maximum storage capacity of 64-bits.

If, however, what you meant was that the bits for each value were as you indicated:

length of DId = 8 BITS    Value = 0 to 255
length of BId = 5 BITS    Value = 0 to 31
length of DocId = 7 BITS  Value = 0 to 127
length of OpId = 4 BITS   Value = 0 to 15

Then you could store this in a long as the total size is only 24-bits.

You could do this by using bit shifting:

long Id = (long)((DId << 16) + (BId << 11) + (DocId << 4) + OpId);
Martin
  • 16,093
  • 1
  • 29
  • 48
  • You are correct that there is not enough bits in a long to do what he's trying to do. Another alternative though would be to create a `struct` that contains 2 `long` variables, giving him a total of 128 bits. He could then store the MSB in one variable and the LSB in the other. – Icemanind Jan 23 '19 at 15:14
  • I try to use this solution, but it's get me duplicated values! – Jourmand Jan 26 '19 at 06:33
  • @Jourmand That's fairly obvious because you can't fit 82-bits into a 64-bit number, as I already stated in the answer and several comments – Martin Feb 07 '19 at 00:01