Issue 3789, stucts equality

bearophile bearophileHUGS at lycos.com
Thu Mar 29 16:36:07 PDT 2012


Alvaro:

> BTW, today I encountered a problem that is probably related to this bug.
> 
> if you have a map with BigInt as key, it duplicates keys:
> 
> int[BigInt] a;
> a[BigInt(3)] = 1;
> a[BigInt(3)] = 2;
> writeln(a);
> 
> prints
> 
> [3:2, 3:1]

Thank you for your example.

BigInt usage has several other problems, this is only a partial sample of them:

-----------------------------

import std.bigint;
void main() {
    BigInt[10] a;
    a[0] = 1; // OK
    a[] = 1; // Error
}


test.d(5): Error: cannot implicitly convert expression (1) of type int to BigInt[]

-----------------------------

import std.bigint;
void main() {
    BigInt b;
    switch (b) {
        case BigInt(0): break;
        default: break;
    }
}


test2.d(4): Error: 'b' is not of integral type, it is a BigInt
test2.d(5): Error: case must be a string or an integral constant, not BigInt(BigUint([0u]),false)

-----------------------------

import std.bigint;
struct Count(T) {
    T n;
    this(T n_) { this.n = n_; }
    const bool empty = false;
    @property T front() { return n; }
    void popFront() { n++; } // line 7
}
void main() {
    auto co = Count!BigInt(BigInt(0));
    foreach (b; co) {}
}


test2.d(7): Error: var has no effect in expression (__pitmp877)
test2.d(10): Error: template instance test.Count!(BigInt) error instantiating

-----------------------------

You can't compile this program:


import std.stdio, std.bigint;

BigInt positiveIntegerPow(in BigInt inBase, in BigInt inExp) pure nothrow
in {
    assert(inBase >= 0 && inExp >= 0);
} out(result) {
    assert(result >= 0);
} body {
    BigInt base = inBase;
    BigInt exp = inExp;
    auto result = BigInt(1);
    while (exp) {
        if (exp & 1)
            result *= base;
        exp >>= 1;
        base *= base;
    }

    return result;
}

void main() {
    writeln(positiveIntegerPow(BigInt(5), BigInt(6)));
}


You have to change it to:


import std.stdio, std.bigint;

BigInt positiveIntegerPow(in BigInt inBase, in BigInt inExp)
in {
    assert(cast()inBase >= 0 && cast()inExp >= 0);
} out(result) {
    assert(cast()result >= 0);
} body {
    BigInt base = cast()inBase;
    BigInt exp = cast()inExp;
    auto result = BigInt(1);
    while (exp != 0) {
        if (exp % 2)
            result *= base;
        exp >>= 1;
        base *= base;
    }

    return result;
}

void main() {
    writeln(positiveIntegerPow(BigInt(5), BigInt(6)));
}


The problems in that little program are:
- You can't assign a const BigInt to a nonconst one.
- BigInt operations aren't pure or nothrow
- while(exp) is not supported
- if if(exp & 1) is not supported
- assert(result>=0); where result is const is not supported.

Bye,
bearophile


More information about the Digitalmars-d mailing list