* Bug 15535 fixed: sign(int8(0)) was wrong. sign() page improved
[scilab.git] / scilab / modules / elementary_functions / sci_gateway / cpp / sci_sign.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2014 - Scilab Enterprises - Anais AUBERT
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15 /*--------------------------------------------------------------------------*/
16 #include <string.h>
17 #include "elem_func_gw.hxx"
18 #include "function.hxx"
19 #include "double.hxx"
20 #include "int.hxx"
21 #include "overload.hxx"
22
23 extern "C"
24 {
25 #include "basic_functions.h"
26 #include "Scierror.h"
27 }
28
29 /*--------------------------------------------------------------------------*/
30 types::Function::ReturnValue sci_sign(types::typed_list &in, int _iRetCount, types::typed_list &out)
31 {
32     int iRows   = 0;
33     int iCols   = 0;
34     int iType   = 0;
35     int* piAddr = NULL;
36
37     double *pdblReal    = NULL;
38     double *pdblImg     = NULL;
39     double *pdblRealRet = NULL;
40     double *pdblImgRet  = NULL;
41
42     if (in.size() != 1)
43     {
44         Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "sign", 1);
45         return types::Function::Error;
46     }
47
48     if (_iRetCount > 1)
49     {
50         Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "sign", 1);
51         return types::Function::Error;
52     }
53
54     if (in[0]->isDouble())
55     {
56         types::Double* pDblIn = in[0]->getAs<types::Double>();
57         int dims = pDblIn->getDims();
58         int *dimsArray = pDblIn->getDimsArray();
59         int size = pDblIn->getSize();
60
61         if (pDblIn->isComplex())
62         {
63             types::Double* pOut = new types::Double(dims, dimsArray, true);
64             double *dOutR   = pOut->getReal();
65             double *dOutImg = pOut->getImg() ;
66             double *dInR    = pDblIn->getReal();
67             double *dInImg  = pDblIn->getImg() ;
68
69             for (int i = 0; i < size; i++)
70             {
71                 double dblTemp = dpythags(dInR[i], dInImg[i]);
72                 if (dblTemp == 0)
73                 {
74                     dOutR[i] = 0;
75                     dOutImg[i] = 0;
76                 }
77                 else
78                 {
79                     dOutR[i] =  dInR[i] / dblTemp;
80                     dOutImg[i] = dInImg[i] / dblTemp;
81                 }
82             }
83
84             out.push_back(pOut);
85         }
86         else
87         {
88             types::Double* pOut = new types::Double(dims, dimsArray);
89             double * dOutR  = pOut->getReal();
90             double * dInR   = pDblIn->getReal();
91
92             for (int i = 0; i < size; i++)
93             {
94                 dOutR[i] = dsignsEx(dInR[i]);
95             }
96
97             out.push_back(pOut);
98         }
99     }
100     else if(in[0]->isInt())
101     {
102         switch (in[0]->getType())
103         {
104             case types::InternalType::ScilabInt8 :
105                 out.push_back(in[0]->getAs<types::Int8>()->sign());
106                 break;
107             case types::InternalType::ScilabUInt8 :
108                 out.push_back(in[0]->getAs<types::UInt8>()->sign());
109                 break;
110             case types::InternalType::ScilabInt16 :
111                 out.push_back(in[0]->getAs<types::Int16>()->sign());
112                 break;
113             case types::InternalType::ScilabUInt16 :
114                 out.push_back(in[0]->getAs<types::UInt16>()->sign());
115                 break;
116             case types::InternalType::ScilabInt32 :
117                 out.push_back(in[0]->getAs<types::Int32>()->sign());
118                 break;
119             case types::InternalType::ScilabUInt32 :
120                 out.push_back(in[0]->getAs<types::UInt32>()->sign());
121                 break;
122             case types::InternalType::ScilabInt64 :
123                 out.push_back(in[0]->getAs<types::Int64>()->sign());
124                 break;
125             case types::InternalType::ScilabUInt64 :
126                 out.push_back(in[0]->getAs<types::UInt64>()->sign());
127                 break;
128         }
129     }
130     else
131     {
132         std::wstring wstFuncName = L"%" + in[0]->getShortTypeStr() + L"_sign";
133         return Overload::call(wstFuncName, in, _iRetCount, out);
134     }
135
136     return types::Function::OK;
137 }
138 /*--------------------------------------------------------------------------*/