Question

Suite à cette question , quelle serait la meilleure façon de représenter un objet System.Decimal dans un tampon protocole?

Était-ce utile?

La solution

Eh bien, protobuf-net simplement gérer pour vous; il ruisseler les propriétés des types, et a un support complet pour decimal. Comme il n'y a aucun moyen direct d'exprimer en proto <=>, il ne sera pas (actuellement) génèrent une propriété d'un fichier <=> « .proto », mais ce serait un beau coup sec de reconnaître un certain type commun ( "BCL .Decimal » ou similaire) et l'interpréter comme décimal.

En ce qui concerne le représenter - j'avais un document de discussion href="http://code.google.com/p/protobuf-net/wiki/DotNetTypes" sur ce (maintenant hors de ce jour, je pense) dans la zone wiki protobuf-net; il y a maintenant une version de travail dans protobuf net que le simple fait pour vous.

Sans doute Jon et je vais marteler ceci plus tard ;-P aujourd'hui

La version protobuf net de cette (en .proto) est quelque chose comme ( ):

message Decimal {
  optional uint64 lo = 1; // the first 64 bits of the underlying value
  optional uint32 hi = 2; // the last 32 bis of the underlying value
  optional sint32 signScale = 3; // the number of decimal digits, and the sign
}

Autres conseils

Marc et moi avons des plans très vagues à venir avec une bibliothèque « message commun PB » de sorte que vous pouvez représenter des types assez communs (date / heure et décimale jaillissant instantanément à l'esprit) d'une manière commune, avec les conversions disponibles. NET et Java (et quoi que ce soit quelqu'un d'autre veut contribuer).

Si vous êtes heureux de coller à .NET, et vous êtes à la recherche de compacité, je vais peut-être avec quelque chose comme:

message Decimal {

    // 96-bit mantissa broken into two chunks
    optional uint64 mantissa_msb = 1;
    optional uint32 mantissa_lsb = 2;

    required sint32 exponent_and_sign = 3;
}

Le signe peut juste être représenté par le signe de exponent_and_sign, avec l'exposant étant la valeur absolue.

Faire les deux parties de la mantisse facultative signifie que 0 est représenté très compacte (mais toujours de différencier entre 0m et 0.0000m etc). exponent_and_sign pourrait être en option et si nous voulions vraiment.

Je ne sais pas sur le projet de Marc, mais dans mon port que je produis des classes partielles, de sorte que vous pouvez le mettre une conversion entre System.Decimal et Protobuf.Common.Decimal (ou autre) dans la classe partielle.

Je mis en place un patch pour protobuf-csharp-port avec des crochets qui génère des classes protobuf avec Decimal natif et struct DateTime. Format des fils sages, ils sont représentés par deux « intégrés » messages proto.

Voici le lien: https://code.google.com/p/protobuf-csharp-port/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status % 20Priority% 20Milestone% 20Owner% 20Summary & groupby = & sort = & id = 78

Un peu plus simple à mettre en œuvre l'approche de Jon ou de Marc est de stocker sous forme de 4 valeurs qui sint32 cartes commodément trivialement à la sortie de Decimal.GetBits () .

Le fichier proto ressemblera:

message ProtoDecimal {
    sint32 v1 = 1;
    sint32 v2 = 2;
    sint32 v3 = 3;
    sint32 v4 = 4;
}

Et le convertisseur sera:

public decimal ConvertToDecimal(AbideDecimal value)
{
    return new decimal(new int[] { value.V1, value.V2, value.V3, value.V4 });
}

public ProtoDecimal ConvertFromDecimal(decimal value)
{
    var bits = decimal.GetBits(value);
    return new ProtoDecimal 
    {
        V1 = bits[0],
        V2 = bits[1],
        V3 = bits[2],
        V4 = bits[3]
    }
}

Cela pourrait ne pas être aussi simple dans d'autres langues, mais si vous suffit de cibler C # alors il prendra le même maximum de 16 octets que l'autre approche (bien que des valeurs telles que 0 pourrait ne pas être aussi compacte stockée - I ne savent pas assez sur les détails complexes de la façon dont ints protobuf magasins), tout en étant beaucoup plus clair pour les programmeurs muets-muets comme moi :)

Il est évident que vous devrez course les chevaux si vous voulez la performance du test mais je doute qu'il y ait beaucoup en elle.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top