cmplx01.cpp

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 572 行 · 第 1/2 页

CPP
572
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*  Copyright (c) 2004-2006 The Open Watcom Contributors. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  This file contains the functional test from the complex
*               template. These tests do not exercise the precision of
*               complex calculations. The checks against expected values
*               are done to a limited number of significant figures. They
*               are only intended to verify that the correct algorithm
*               is being used in the computation.
****************************************************************************/

#include <cmath>
#include <complex>
#include <iostream>

// Really should check all three floating point types.
typedef std::complex<double> complex;

#define CLOSE_ENOUGH(x, y) (std::abs(((x)/(y)) - 1.0) <= 1.0E-3)

static bool close_enough( const complex &x, const complex &y )
{
  if (CLOSE_ENOUGH( x.real( ), y.real( ) ) &&
      CLOSE_ENOUGH( x.imag( ), y.imag( ) ) )
    return( true );
  return( false );
}


bool construct_test( )
{
  bool rc = true;

  complex z1;
  complex z2( 1.0 );
  complex z3( 1.0, -1.0 );
  complex z4( z3 );

  // Don't use the close_enough() function until basic construction checks.

  if( z1.real( ) != 0.0 || z1.imag( ) != 0.0  ) {
    std::cout << "basic FAIL 0001\n"; rc = false;
  }

  if( z2.real( ) != 1.0 || z2.imag( ) != 0.0 ) {
    std::cout << "basic FAIL 0002\n"; rc = false;
  }

  if( z3.real( ) !=  1.0 || z3.imag( ) != -1.0 ) {
    std::cout << "basic FAIL 0003\n"; rc = false;
  }

  if( z4.real( ) !=  1.0 || z4.imag( ) != -1.0 ) {
    std::cout << "basic FAIL 0004\n"; rc = false;
  }

  return( rc );
}


bool add_test( )
{
  bool rc = true;

  complex z( 1.0, 1.0 );
  complex x;

  x = z + complex( 1.0, 1.0 );
  if( !close_enough( x, complex( 2.0, 2.0 ) ) ) {
    std::cout << "add FAIL 0001\n"; rc = false;
  }

  x = z + complex( 1.0, -2.0 );
  if( !close_enough( x, complex( 2.0, -1.0 ) ) ) {
    std::cout << "add FAIL 0002\n"; rc = false;
  }

  x = z + complex( -2.0, 1.0 );
  if( !close_enough( x, complex( -1.0, 2.0 ) ) ) {
    std::cout << "add FAIL 0003\n"; rc = false;
  }

  x = z + complex( -2.0, -2.0 );
  if( !close_enough( x, complex( -1.0, -1.0 ) ) ) {
    std::cout << "add FAIL 0004\n"; rc = false;
  }

  return( rc );
}


bool subtract_test( )
{
  bool rc = true;

  complex z( 1.0, 1.0 );
  complex x;

  x = z - complex( 0.5, 0.5 );
  if( !close_enough( x, complex( 0.5, 0.5 ) ) ) {
    std::cout << "subtract FAIL 0001\n"; rc = false;
  }

  x = z - complex( 2.0, -0.5 );
  if( !close_enough( x, complex( -1.0, 1.5 ) ) ) {
    std::cout << "subtract FAIL 0002\n"; rc = false;
  }

  x = z - complex( 2.0, 2.0 );
  if( !close_enough( x, complex( -1.0, -1.0 ) ) ) {
    std::cout << "subtract FAIL 0003\n"; rc = false;
  }

  x = z - complex( -0.5, 2.0 );
  if( !close_enough( x, complex( 1.5, -1.0 ) ) ) {
    std::cout << "subtract FAIL 0004\n"; rc = false;
  }

  return( rc );
}


bool multiply_test( )
{
  bool rc = true;

  complex z( 2.0, 2.0 );
  complex x;

  x = z * complex( 1.0, 1.5 );
  if( !close_enough( x, complex( -1.0, 5.0 ) ) ) {
    std::cout << "multiply FAIL 0001\n"; rc = false;
  }

  x = z * complex( 1.0, 0.1 );
  if( !close_enough( x, complex( 1.8, 2.2 ) ) ) {
    std::cout << "multiply FAIL 0002\n"; rc = false;
  }

  x = z * complex( -0.175, -0.425 );
  if( !close_enough( x, complex( 0.5, -1.2 ) ) ) {
    std::cout << "multiply FAIL 0003\n"; rc = false;
  }

  x = z * complex( -0.25, 0.0 );
  if( !close_enough( x, complex( -0.5, -0.5 ) ) ) {
    std::cout << "multiply FAIL 0004\n"; rc = false;
  }

  return( rc );
}


bool divide_test( )
{
  bool rc = true;

  complex z( 2.0, 2.0 );
  complex x;

  x = z / complex( 1.0, 1.5 );
  if( !close_enough( x, complex( 1.5385, -0.3077 ) ) ) {
    std::cout << "divide FAIL 0001\n"; rc = false;
  }

  x = z / complex( 0.9, 0.1 );
  if( !close_enough( x, complex( 2.4390, 1.9512 ) ) ) {
    std::cout << "divide FAIL 0002\n"; rc = false;
  }

  x = z / complex( -1.2235, 0.0941 );
  if( !close_enough( x, complex( -1.5, -1.75 ) ) ) {
    std::cout << "divide FAIL 0003\n"; rc = false;
  }

  x = z / complex( 0.0941, -1.2235 );
  if( !close_enough( x, complex( -1.5, 1.75 ) ) ) {
    std::cout << "divide FAIL 0004\n"; rc = false;
  }

  return( rc );
}

bool abs_test( )
{
  using std::abs;

  bool rc = true;

  double result = abs( complex( 1.0, 1.0 ) );
  if( !CLOSE_ENOUGH( result, 1.4142 ) ) {
    std::cout << "abs FAIL 0001\n"; rc = false;
  }

  result = abs( complex( -1.0, 0.0 ) );
  if( !CLOSE_ENOUGH( result, 1.0 ) ) {
    std::cout << "abs FAIL 0002\n"; rc = false;
  }

  result = abs ( complex( 0.0, 0.0 ) );
  if( abs( result ) >= 1.0E-3 ) {
    std::cout << "abs FAIL 0003\n"; rc = false;
  }

  return( rc );
}

bool arg_test( )
{
  using std::arg;
  bool rc = true;

  double result = arg( complex( 1.0, 1.0 ) );
  if( !CLOSE_ENOUGH( result, 7.854E-1 ) ) {
    std::cout << "arg FAIL 0001\n"; rc = false;
  }

  result = arg( complex( 1.0, -0.1 ) );
  if( !CLOSE_ENOUGH( result, -9.967E-2 ) ) {
    std::cout << "arg FAIL 0002\n"; rc = false;
  }

  result = arg( complex( -0.1, -1.0 ) );
  if( !CLOSE_ENOUGH( result, -1.670 ) ) {
    std::cout << "arg FAIL 0003\n"; rc = false;
  }

  result = arg( complex( -1.0, 2.0 ) );
  if( !CLOSE_ENOUGH( result, 2.034 ) ) {
    std::cout << "arg FAIL 0004\n"; rc = false;
  }
  return( rc );
}

bool polar_test( )
{
  using std::polar;
  bool rc = true;

  complex z = polar( 1.0, 1.0 );
  if( !close_enough( z, complex( 0.5403, 0.8415 ) ) ) {
    std::cout << "polar FAIL 0001\n"; rc = false;
  }

  z = polar( 0.0, 1.0 );
  if( z.real( ) >= 1.0E-3 || z.imag( ) >= 1.0E-3 ) {
    std::cout << "polar FAIL 0002\n"; rc = false;
  }

  z = polar( 1.0, 1.57080 );
  if( z.real( ) >= 1.0E-3 || !CLOSE_ENOUGH( z.imag( ), 1.0 ) ) {
    std::cout << "polar FAIL 0003\n"; rc = false;
  }

  z = polar( 1.0, 3.14159 );
  if( !CLOSE_ENOUGH( z.real( ), -1.0 ) || z.imag( ) >= 1.0E-3 ) {
    std::cout << "polar FAIL 0004\n"; rc = false;
  }

  z = polar( 1.0, -3.14159 );
  if( !CLOSE_ENOUGH( z.real( ), -1.0 ) || z.imag( ) >= 1.0E-3 ) {
    std::cout << "polar FAIL 0005\n"; rc = false;
  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?