-2

これは再現可能な C++ プログラムです。

#include <RInside.h>
#include <Rcpp.h>

int main (int argc, char *argv[])
{
    RInside R (argc, argv);
    SEXP ans = R.parseEval ("m <- 40.702147");

    Rcpp::NumericVector v (ans);           

    for (int i=0; i< v.size(); i++) 
    {           
        std::cout << "In C++ element " << i << " is " << v[i] << std::endl;
    }

    return 0;
}

Makefileはここにあります:

## -*- mode: make; tab-width: 8; -*-
##
## Simple Makefile
##
## TODO: 
##  proper configure for non-Debian file locations,   [ Done ]
##  allow RHOME to be set for non-default R etc

## comment this out if you need a different version of R, 
## and set set R_HOME accordingly as an environment variable
R_HOME :=       $(shell R RHOME)

sources :=      $(wildcard *.cpp)
programs :=         $(sources:.cpp=)


## include headers and libraries for R 
RCPPFLAGS :=        $(shell $(R_HOME)/bin/R CMD config --cppflags)
RLDFLAGS :=         $(shell $(R_HOME)/bin/R CMD config --ldflags)
RBLAS :=        $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS)
RLAPACK :=      $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS)

## if you need to set an rpath to R itself, also uncomment
#RRPATH :=      -Wl,-rpath,$(R_HOME)/lib

## include headers and libraries for Rcpp interface classes
RCPPINCL :=         $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave)
RCPPLIBS :=         $(shell echo 'Rcpp:::LdFlags()'  | $(R_HOME)/bin/R --vanilla --slave)


## include headers and libraries for RInside embedding classes
RINSIDEINCL :=      $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave)
RINSIDELIBS :=      $(shell echo 'RInside:::LdFlags()'  | $(R_HOME)/bin/R --vanilla --slave)

## compiler etc settings used in default make rules
CXX :=          $(shell $(R_HOME)/bin/R CMD config CXX)
CPPFLAGS :=         -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS)
CXXFLAGS :=         $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS)
LDLIBS :=       $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS)

all:            $(programs)
            @test -x /usr/bin/strip && strip $^

run:            $(programs)
            @for p in $(programs); do echo; echo "Running $$p:"; ./$$p; done

clean:
            rm -vf $(programs)
            rm -vrf *.dSYM

runAll:
            for p in $(programs); do echo "Running $$p"; ./$$p; done

このプログラムの出力:

In C++ element 0 is 40.7021

問題は、値40.702147が に「切り捨て」られていること40.7021です。
いっぱいにしたい。
抜け道は何ですか?

4

2 に答える 2

7

値自体は切り捨てられていません(a)cout出力ストリームは出力にデフォルトを使用しています。

iomanipヘッダーを調べて、次のような特定の出力形式を強制する方法を見つけることができます。

std::cout << std::setprecision (9) << v[i] << '\n';

この完全なプログラムは次のとおりです。

#include <iostream>
#include <iomanip>

int main (void) {
    double d = 40.702147;
    std::cout << d << '\n';
    std::cout << std::setprecision (9) << d << '\n';
    return 0;
}

出力:

40.7021
40.702147

(a) : IEEE754 の倍精度値として正確に表現できない場合は切り捨てられる可能性があることに注意してください。しかし、ここではそうではありません。

于 2012-07-30T10:14:03.523 に答える
4

std::cout精度は次の方法で指定できます。

std::cout.precision(16);

または使用

std::cout << std::setprecision (9) << val;

paxdiablo と Joachim が提案したように

于 2012-07-30T10:15:54.620 に答える