mathe172
Goto Top

VS Express 2012 LNK2019: Verweis auf nicht aufgelöstes externes Symbol

Hallo,

ich erhalte den folgenden Fehler, beim Versuch, mein Projekt zu kompilieren:

Fehler	1	error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall ifm::integer::integer(void)" (??0integer@ifm@@QAE@XZ)" in Funktion "_main".	C:\Users\Benutzer\documents\visual studio 2012\Projects\Test\Test\power20.obj	Test  
Fehler	2	error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl ifm::operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class ifm::integer const &)" (??6ifm@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV12@ABVinteger@0@@Z)" in Funktion "_main".	C:\Users\Benutzer\documents\visual studio 2012\Projects\Test\Test\power20.obj	Test  
Fehler	3	error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""class std::basic_istream<char,struct std::char_traits<char> > & __cdecl ifm::operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class ifm::integer &)" (??5ifm@@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV12@AAVinteger@0@@Z)" in Funktion "_main".	C:\Users\Benutzer\documents\visual studio 2012\Projects\Test\Test\power20.obj	Test  
Fehler	4	error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""class ifm::integer __cdecl ifm::operator*(class ifm::integer const &,class ifm::integer const &)" (??Difm@@YA?AVinteger@0@ABV10@0@Z)" in Funktion "_main".	C:\Users\Benutzer\documents\visual studio 2012\Projects\Test\Test\power20.obj	Test  
Fehler	5	error LNK1120: 4 nicht aufgelöste Externe	C:\Users\Benutzer\documents\visual studio 2012\Projects\Test\Debug\Test.exe	Test

Die Umstände sind folgende: Wir bekommen von der Uni eine virtuelle Ubuntu Maschine, auf der wir programmieren und kompilieren können. Das ganze ist komplett vorkonfiguriert, unter anderem gibt es ein paar zusätzliche Bibliotheken. Nun wollte ich das ganze aber mit VS Express lösen. BeimBenutzen besagter zusätzlichen Bibliotheken bekomme ich aber obige Fehler. Ich habe den Include-Pfad so angepasst, dass er die Dateien findet, jedoch muss ich wohl etwas übersehen haben face-smile

Die Dateien schauen wie folgt aus:
power20.cpp:
//Informatik - Serie 1 - Aufgabe 3
//Programm: power20.cpp
//Autor: ***

#include<iostream>
#include<IFM\integer.h>

int main() {
  std::cout << "Compute a^20 for a=? ";  
  ifm::integer a;
  std::cin >> a;

  //computation
  ifm::integer b = a * a;
  b = b * b;
  ifm::integer c = b * b;
  c = c * c;
  
  //output b * c, i.e., a^20
  std::cout << a << "^20 = " << b * c << ".\n";  
  return 0;
}

integer.h:
// Programm: integer.h
// defines integer numbers of arbitrary size

#include <istream>
#include <ostream>
#include <deque>
#include <string>

namespace ifm {

  class integer {

  public:  
    // constructors
    // ------------
    integer();                 // 0
    integer(int i);            // i
    integer(unsigned int i);   // i
    integer(float f);          // f     
    integer(double d);         // d
    integer(std::string s);         // s

    // arithmetic operators (with the standard semantics)
    // --------------------------------------------------
    integer  operator-() const;   
    integer& operator+=(const integer& x);
    integer& operator++();
    integer  operator++(int);
    integer& operator-=(const integer& x);
    integer& operator--();
    integer  operator--(int);
    integer& operator*=(const integer& x);
    integer& operator/=(const integer& x);
    integer& operator%=(const integer& x);
    
    // conversion to double
    // --------------------------------------------------
    double to_double() const;
    
   
    // global friend operators
    // -----------------------
    friend bool operator==(const integer& x, const integer& y);
    friend bool operator<(const integer& x, const integer& y);
    friend std::ostream& operator<<(std::ostream& o, const integer& x);
    friend std::istream& operator>>(std::istream& i, integer& x);

  private:  
    // typedefs
    // --------
    typedef std::deque<unsigned int>     Seq;
    typedef Seq::iterator                It;
    typedef Seq::const_iterator          Cit;
    typedef Seq::const_reverse_iterator  Crit;

    // data members
    // ------------
    // an integer is represented by a base, a sign, and a sequence
    // of digits in the given base.

    // the base must be a power of 10 to facilitate decimal input and output
    static const unsigned int power_ = 4;
    static const unsigned int base_ = 10000;
   
    // the sign
    bool sign_; // false <=> negative

    // the sequence
    Seq seq_;
    // represents the nonnegative number
    // 
    //  \sum_{i=0}^{seq_.size()-1} seq_[i]*base_^i
    // The number 0 is represented by a length-1-sequence with seq_ == 0

    // private member functions
    // ------------------------
  
    // PRE: seq_ is empty
    // POST: seq_ is initialized to represent the number i  
    void init(unsigned int i);

    // POST: return value is true iff |*this| < |x|.
    bool abs_less(const integer& x) const;

    // POST: seq_ is updated to represent |*this| + |x|    
    integer& add(const integer& x);

    // PRE: |x| <= |*this|
    // POST: seq_ is updated to represent |*this| - |x|
    integer& subtract(const integer& x);

    // PRE: *this != 0, x < base_
    // POST: seq_ is updated to represent |*this| * |x|
    integer& mult(unsigned int x);
    
    // PRE: x != 0
    // POST: *this is replaced by the remainder of the division
    //       of *this by x; r holds the result of the division
    integer& div(const integer& x, integer& r);

    // PRE: s >= 0
    // POST: *this is multiplied by base_^s
    integer& leftshift (int s);

    // POST: returns true true iff highest significand digit is nonzero
    bool is_normalized() const;

    // POST: returns true iff *this has value 0
    bool is_zero() const;
  };

  // global operators
  // ----------------
  bool operator!=(const integer& x, const integer& y);
  bool operator<=(const integer& x, const integer& y);
  bool operator>(const integer& x, const integer& y);
  bool operator>=(const integer& x, const integer& y);

  integer operator+(const integer& x, const integer& y);
  integer operator-(const integer& x, const integer& y);
  integer operator*(const integer& x, const integer& y);
  integer operator/(const integer& x, const integer& y);
  integer operator%(const integer& x, const integer& y);
}

integer.cpp:
// Programm: integer.cpp
// Implements integer numbers of arbitrary size

#include <deque>
#include <istream>
#include <ostream>
#include<iterator>
#include <cassert>
#include <cmath>
#include <cctype>
#include <limits>
#include <IFM/integer.h>

namespace ifm {

  // Implementation: public member functions
  // ---------------------------------------
  integer::integer() : sign_(true) 
  {
    seq_.push_back(0);    
    assert (is_normalized());
  }

  void integer::init(unsigned int i) 
  {
    assert (seq_.empty());
    if (i == 0) 
      seq_.push_back(0);
    else
      while (i > 0) {
        seq_.push_back(i % base_);
        i /= base_;
      }
  }

  integer::integer(int i) : sign_(i >= 0)
  {
    if (i < 0) i = -i;
    init(i);
    assert (is_normalized());
  }
  
  integer::integer(unsigned int i) : sign_(true)
  {
    init(i);
    assert (is_normalized());
  }

  integer::integer(float f) : sign_ (f >= 0)
  {
    int exp; 
    float m = std::frexp (std::abs(f), &exp); 
    // if |f| is nonzero, then |f| = 0.b_1b_2....b_24 * 2^exp 
    // the integer resulting from this is obtained by moving the
    // comma exp places to the right (and forgetting about the digits
    // that may still follow)
    integer b;
     for (; exp > 0; --exp) {
      b *= 2;
      if (m >= 0.5f) {
	b += 1;
	m = 2.0f * (m - 0.5f);
      } else
	m = 2.0f * m;
    }  
    seq_ = b.seq_;   
    assert (is_normalized());
  }

  integer::integer(double d) : sign_ (d >= 0)
  {
    int exp; 
    double m = std::frexp (std::abs(d), &exp); 
    // if |d| is nonzero, then |d| = 0.b_1b_2....b_53 * 2^exp 
    // the integer resulting from this is obtained by moving the
    // comma exp places to the right (and forgetting about the digits
    // that may still follow)
    integer b;
    for (; exp > 0; --exp) {
      b *= 2;
      if (m >= 0.5) {
	b += 1;
	m = 2.0 * (m - 0.5);
      } else
	m = 2.0 * m;
    }
    seq_ = b.seq_;
    assert (is_normalized());
  }
  
  integer::integer(std::string s) : sign_(true) {
    integer b;
    
    unsigned int size = s.size();
    int index = 0;
    
    if (size > 0) {
      if (s == '+') ++index;  
      else if (s == '-') {  
        ++index;
        sign_ = false;
      }
      
      while (static_cast<unsigned int>(index) < size) {
        b *= 10;
        b += s[index] - '0'; // only works for digits obviously  
        ++index;
      }
      
      
    }
    
    seq_ = b.seq_;
    assert (is_normalized());
  }

  bool integer::abs_less(const integer& x) const
  {
    if (seq_.size() < x.seq_.size()) return true;
    if (seq_.size() > x.seq_.size()) return false;
    Crit i = seq_.rbegin();
    Crit j = x.seq_.rbegin();
    for (; i != seq_.rend(); ++i, ++j) {
      if (*i < *j) return true;
      if (*i > *j) return false;
    }
    return false;
  }

  integer integer::operator-() const
  {
    integer x = *this;
    if (!is_zero()) x.sign_ = !sign_;
    return x;
  }
  
  integer& integer::operator+=(const integer& x)
  {
    if (sign_ == x.sign_) return add(x);
    if (!abs_less(x)) return subtract(x);
    integer z = x;
    z.subtract(*this);
    std::swap(z, *this);    
    assert (is_normalized());
    return *this;
  }

  integer& integer::operator++()
  {
    return *this += 1;
  }  

  integer integer::operator++(int)
  {
    integer z = *this;
    *this += 1;
    return z;
  }
  
  integer& integer::operator-=(const integer& x)
  {
    if (sign_ != x.sign_) return add(x);
    if (!abs_less(x)) return subtract(x);
    integer z = x;
    z.subtract(*this);
    z.sign_ = !z.sign_;
    std::swap(z, *this);    
    assert (is_normalized());
    return *this;
  }

  integer& integer::operator--()
  {
    return *this -= 1;
  } 

  integer integer::operator--(int)
  {
    integer z = *this;
    *this -= 1;
    return z;
  }

  integer& integer::operator*=(const integer& x)
  {
    if (is_zero()) return *this;
    integer r = 0;
    r.sign_ = (sign_ && x.sign_ || !sign_ && !x.sign_);
    for (Cit i = x.seq_.begin(); i != x.seq_.end(); ++i) {
      integer z = *this;
      z.mult(*i);
      r.add(z);
      seq_.push_front(0);
    }
    std::swap(r, *this);
    assert (is_normalized());
    return *this;
  }

  integer& integer::operator/=(const integer& x)
  {
    assert(!x.is_zero());
    integer r;
    div(x, r);
    std::swap(*this, r);   
    assert (is_normalized());
    return *this;
  }

  integer& integer::operator%=(const integer& x)
  {
    assert(!x.is_zero());
    integer r;
    return div(x, r);
  }

  integer& integer::leftshift(int s)
  {
    assert (s >= 0);
    if (!is_zero())
      for (int i=0; i<s; ++i)
	seq_.push_front(0);
    return *this;
  }
  
  double integer::to_double() const {
    
    double ret = 0.0;
    unsigned int no_double_digits = std::numeric_limits<double>::digits;
    
    std::deque<unsigned short> binary_digits;
    integer tmp = *this;
    if (tmp < 0) tmp *= -1;
    while (tmp != 0) {
      binary_digits.push_front(tmp % 2 == 1 ? 1 : 0);
      tmp /= 2;
    }
    
    for (std::deque<unsigned short>::iterator it = binary_digits.begin(); it != binary_digits.end(); ++it, --no_double_digits) {
      if (no_double_digits > 0) ret += 0.5 * *it;
      ret *= 2;
    }
    return this->sign_ ? ret : -ret;
  }

  // Implementation: private member functions
  // ----------------------------------------
  integer& integer::add(const integer& x)
  {
    while (seq_.size() < x.seq_.size()) seq_.push_back(0);
    bool carry = false;
    It i = seq_.begin(); 
    for (Cit j = x.seq_.begin(); j != x.seq_.end(); ++j, ++i) {
      *i += *j;
      if (carry) ++*i;
      carry = (*i >= base_);
      if (carry) *i -= base_;
    }
    if (!carry) return *this;
    for (; i != seq_.end(); ++i)
      if (++*i == base_) *i = 0; else return *this;
    seq_.push_back(1);
    return *this;
  }

  integer& integer::subtract(const integer& x)
  {
    assert(!abs_less(x));
    It i = seq_.begin();
    bool carry = false;
    for (Cit j = x.seq_.begin(); j != x.seq_.end(); ++j, ++i) {
      assert(i != seq_.end());
      *i += base_ - *j;
      if (carry) --*i;
      carry = (*i < base_);
      if (!carry) *i -= base_;
    }
    if (carry) {
      assert(i != seq_.end());
      while (*i == 0) {
        *(i++) = base_ - 1;
        assert(i != seq_.end());
      }
      --*i;
    }
    while (seq_.back() == 0) 
      if (seq_.size() == 1) { 
        sign_ = true; 
        return *this;
      } else
        seq_.pop_back();
    return *this;
  }

  integer& integer::mult(unsigned int x) 
  {
    assert (!is_zero());
    if (x == 0) return *this = 0;
    assert(x < base_);
    unsigned int carry = 0;
    for (It i = seq_.begin(); i != seq_.end(); ++i) {
      carry = *i * x + carry;
      *i = carry % base_;
      carry /= base_;
    }
    if (carry > 0) seq_.push_back(carry);
    return *this;
  }

  integer& integer::div(const integer& x, integer& r)
  {
    if (abs_less(x)) {
      r = 0;
      return *this;
    }
    // compute sign
    r.sign_ = (sign_ && x.sign_ || !sign_ && !x.sign_);
    r.seq_.clear();

    // align divisor and initialize upper and lower bound for
    // binary search for multiplicator
    integer d = x;
    unsigned int sh = 1;
    unsigned int denh = d.seq_.back(); // highest digit of denominator
    while (d.seq_.size() < seq_.size()) {
      d.seq_.push_front(0);
      ++sh;
    }
    if (abs_less(d)) {
      d.seq_.pop_front();
      --sh;
    }

    do {
      // binary search for multiplicator in suitable range [low,upp)
      // there are three cases:
      // (a) *this < d
      // (b) *this >= d and both have the same size
      // (c) *this >= d and *this has one digit more
      unsigned int numh; // leading 0, 1, or 2 digits of *this 
      if (abs_less (d)) 
	numh = 0;  // case (a)
      else {		    
	numh = seq_.back(); // cases (b), (c)
	if (d.seq_.size() < seq_.size())
	  numh =  numh * base_ + seq_[seq_.size()-2]; // case (c)
      }    
      unsigned int low = numh / (denh + 1);
      unsigned int upp = numh / denh + 1;
      if (upp > base_) upp = base_;
      unsigned int t;     
      integer dt;      
      // Invariant: multiplicator in [low, upp)
      do {
        t = (low + upp) / 2;      
	dt = d;
        dt.mult(t);
        if (abs_less(dt)) upp = t; else low = t;
      } while (upp - low > 1);
     
      // subtract multiple of divisor
      r.seq_.push_front(low);
      if (t != low) {
	dt = d;
	dt.mult(low);
      }
      subtract(dt);
      
      // cut off trailing zero in divisor
      d.seq_.pop_front();
    } while (--sh > 0);
    assert (is_normalized());
    return *this;
  }

  bool integer::is_normalized() const
  {
    return !seq_.empty() && (seq_.size()==1 || seq_[seq_.size()-1] != 0);
  }

  bool integer::is_zero() const
  {
    return seq_.size()==1 && seq_ == 0;
  }

  // global operators
  // ----------------
  bool operator==(const integer& x, const integer& y)
  {
    return x.sign_ == y.sign_ && x.seq_ == y.seq_;
  }
  
  bool operator!=(const integer& x, const integer& y) { return !(x == y); }

  bool operator<(const integer& x, const integer& y)
  {
    if (x.sign_ != y.sign_) return x.sign_ < y.sign_;
    if (x.sign_) return x.abs_less(y);
    return y.abs_less(x);
  }
  
  bool operator<=(const integer& x, const integer& y) { return !(y < x); }
  bool operator> (const integer& x, const integer& y) { return y < x;    }
  bool operator>=(const integer& x, const integer& y) { return !(x < y); }

  integer operator+(const integer& x, const integer& y)
  {
    integer z = x;
    z += y;
    return z;
  }
  
  integer operator-(const integer& x, const integer& y)
  {
    integer z = x;
    z -= y;
    return z;
  }
  
  integer operator*(const integer& x, const integer& y)
  {
    integer z = x;
    z *= y;
    return z;
  }

  integer operator/(const integer& x, const integer& y)
  {
    integer z = x;
    z /= y;
    return z;
  }

  integer operator%(const integer& x, const integer& y)
  {
    integer z = x;
    z %= y;
    return z;
  }


  std::ostream& operator<<(std::ostream& o, const integer& x)
  {
    if (!x.sign_) o << "-";        
    bool leading_zeros = true; // need to skip them
    for (integer::Crit i = x.seq_.rbegin(); i != x.seq_.rend(); ++i) {
      std::deque<unsigned int> decimal_digits;
      unsigned int decimal_number = *i;
      for (unsigned int j=0; j<integer::power_; ++j) {
	decimal_digits.push_front(decimal_number % 10);
	decimal_number /= 10;
      }
      for (unsigned int j=0; j<integer::power_; ++j) {
	unsigned int d = decimal_digits[j];
	if (!leading_zeros || d != 0 || j == integer::power_-1) {
	  o << d;
	  leading_zeros = false;
	}   
      }
    }
    return o;
  }

  std::istream& operator>>(std::istream& i, integer& x)
  {  
    const char zero = '0';  
    char c;
    for (;;) {
      c = i.peek();
      if (std::isspace(c)) 
	i.get();
      else
	break; // all whitespaces eaten
    }
    // check for sign
    bool negative = false;
    if (c == '+' || c == '-') {  
      negative = (c == '-');  
      i.get();
      c = i.peek();
    } 
    // now c is the first digit; we collect the digits
    // in bunchs of integer::power_ many
    if (std::isdigit(c)) {
      x = 0;
      unsigned int y = 0;
      unsigned int read = 0;
      unsigned int ten_to_read = 1;
      do { 
	y = 10 * y + (c-zero);
	i.get();
	++read;
	ten_to_read *= 10;
	if (read == integer::power_) {
	  x.leftshift(1);
	  x.seq_ = y; 
	  y = 0;
	  read = 0; ten_to_read = 1;
	}
	c = i.peek();
      } while (std::isdigit(c));
      // handle remaining y
      if (read > 0) x = static_cast<integer>(ten_to_read) * x + static_cast<integer>(y);
      if (negative) x = -x;
    }
    return i;
  }
  
} // namespace math

Leider werde ich aus den Fehlern alles andere als schlau (bin auch neu bei C++) face-sad Weiss jemand vielleicht irgendetwas, das noch fehlt?

MfG,
Mathe172

Content-ID: 218186

Url: https://administrator.de/contentid/218186

Ausgedruckt am: 05.11.2024 um 19:11 Uhr