Math.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Linq.Expressions;
  6. namespace System.Linq.jvm
  7. {
  8. class Math
  9. {
  10. private static readonly Type NULLABLE_TYPE = typeof(Nullable<>);
  11. public static object Evaluate(object a, object b, Type t, ExpressionType et)
  12. {
  13. TypeCode tc = Type.GetTypeCode(t);
  14. if (tc == TypeCode.Object)
  15. {
  16. if (t.GetGenericTypeDefinition() != NULLABLE_TYPE)
  17. {
  18. throw new NotImplementedException(
  19. string.Format(
  20. "Expression with Node type {0} for type {1}",
  21. t.FullName,
  22. tc));
  23. }
  24. return EvaluateNullable(a, b, Type.GetTypeCode(t.GetGenericArguments()[0]), et);
  25. }
  26. return Evaluate(a, b, tc, et);
  27. }
  28. public static object EvaluateNullable(object a, object b, TypeCode tc, ExpressionType et)
  29. {
  30. object o = null;
  31. if (a == null || b == null)
  32. {
  33. if (tc != TypeCode.Boolean)
  34. {
  35. return null;
  36. }
  37. switch (et)
  38. {
  39. case ExpressionType.And:
  40. o = And(a, b);
  41. break;
  42. case ExpressionType.Or:
  43. o = Or(a, b);
  44. break;
  45. case ExpressionType.ExclusiveOr:
  46. o = ExclusiveOr(a, b);
  47. break;
  48. }
  49. }
  50. else
  51. {
  52. o = Evaluate(a, b, tc, et);
  53. }
  54. return Convert2Nullable(o, tc);
  55. }
  56. private static object ExclusiveOr(object a, object b)
  57. {
  58. if (a == null || b == null)
  59. {
  60. return null;
  61. }
  62. return (bool)a ^ (bool)b;
  63. }
  64. public static object Or(object a, object b)
  65. {
  66. if (a == null)
  67. {
  68. if (b == null || !((bool)b))
  69. {
  70. return null;
  71. }
  72. return true;
  73. }
  74. if (b == null)
  75. {
  76. if (a == null || !((bool)a))
  77. {
  78. return null;
  79. }
  80. return true;
  81. }
  82. return (bool)a || (bool)b;
  83. }
  84. public static object And(object a, object b)
  85. {
  86. if (a == null)
  87. {
  88. if (b == null || (bool)b)
  89. {
  90. return null;
  91. }
  92. return false;
  93. }
  94. if (b == null)
  95. {
  96. if (a == null || (bool)a)
  97. {
  98. return null;
  99. }
  100. return false;
  101. }
  102. return (bool)a && (bool)b;
  103. }
  104. private static object Convert2Nullable(object o, TypeCode tc)
  105. {
  106. if (o == null)
  107. {
  108. return null;
  109. }
  110. switch (tc)
  111. {
  112. case TypeCode.Char:
  113. return new Nullable<Char>((Char)o);
  114. case TypeCode.Byte:
  115. return new Nullable<Byte>((Byte)o);
  116. case TypeCode.Decimal:
  117. return new Nullable<Decimal>((Decimal)o);
  118. case TypeCode.Double:
  119. return new Nullable<Double>((Double)o);
  120. case TypeCode.Int16:
  121. return new Nullable<Int16>((Int16)o);
  122. case TypeCode.Int32:
  123. return new Nullable<Int32>((Int32)o);
  124. case TypeCode.Int64:
  125. return new Nullable<Int64>((Int64)o);
  126. case TypeCode.UInt16:
  127. return new Nullable<UInt16>((UInt16)o);
  128. case TypeCode.UInt32:
  129. return new Nullable<UInt32>((UInt32)o);
  130. case TypeCode.SByte:
  131. return new Nullable<SByte>((SByte)o);
  132. case TypeCode.Single:
  133. return new Nullable<Single>((Single)o);
  134. case TypeCode.Boolean:
  135. return new Nullable<Boolean>((Boolean)o);
  136. }
  137. throw new NotImplementedException(
  138. string.Format("No Convert2Nullable defined for type {0} ", tc));
  139. }
  140. public static object Evaluate(object a, object b, TypeCode tc, ExpressionType et)
  141. {
  142. switch (tc)
  143. {
  144. case TypeCode.Boolean:
  145. return Evaluate(Convert.ToBoolean(a), Convert.ToBoolean(b), et);
  146. case TypeCode.Char:
  147. return Evaluate(Convert.ToChar(a), Convert.ToChar(b), et);
  148. case TypeCode.Byte:
  149. return unchecked((Byte)Evaluate(Convert.ToByte(a), Convert.ToByte(b), et));
  150. case TypeCode.Decimal:
  151. return Evaluate(Convert.ToDecimal(a), Convert.ToDecimal(b), et);
  152. case TypeCode.Double:
  153. return Evaluate(Convert.ToDouble(a), Convert.ToDouble(b), et);
  154. case TypeCode.Int16:
  155. return unchecked((Int16)Evaluate(Convert.ToInt16(a), Convert.ToInt16(b), et));
  156. case TypeCode.Int32:
  157. return Evaluate(Convert.ToInt32(a), Convert.ToInt32(b), et);
  158. case TypeCode.Int64:
  159. return Evaluate(Convert.ToInt64(a), Convert.ToInt64(b), et);
  160. case TypeCode.UInt16:
  161. return unchecked((UInt16)Evaluate(Convert.ToUInt16(a), Convert.ToUInt16(b), et));
  162. case TypeCode.UInt32:
  163. return Evaluate(Convert.ToUInt32(a), Convert.ToUInt32(b), et);
  164. case TypeCode.UInt64:
  165. return Evaluate(Convert.ToUInt64(a), Convert.ToUInt64(b), et);
  166. case TypeCode.SByte:
  167. return unchecked((SByte)Evaluate(Convert.ToSByte(a), Convert.ToSByte(b), et));
  168. case TypeCode.Single:
  169. return Evaluate(Convert.ToSingle(a), Convert.ToSingle(b), et);
  170. }
  171. throw new NotImplementedException(
  172. string.Format("Expression with Node type {0} for type {1}", et, tc));
  173. }
  174. public static object NegeteChecked(object a, TypeCode tc)
  175. {
  176. switch (tc)
  177. {
  178. case TypeCode.Char:
  179. return checked(-Convert.ToChar(a));
  180. case TypeCode.Byte:
  181. return checked(-Convert.ToByte(a));
  182. case TypeCode.Decimal:
  183. return checked(-Convert.ToDecimal(a));
  184. case TypeCode.Double:
  185. return checked(-Convert.ToDouble(a));
  186. case TypeCode.Int16:
  187. return checked(-Convert.ToInt16(a));
  188. case TypeCode.Int32:
  189. return checked(-Convert.ToInt32(a));
  190. case TypeCode.Int64:
  191. return checked(-Convert.ToInt64(a));
  192. case TypeCode.UInt16:
  193. return checked(-Convert.ToUInt16(a));
  194. case TypeCode.UInt32:
  195. return checked(-Convert.ToUInt32(a));
  196. case TypeCode.SByte:
  197. return checked(-Convert.ToSByte(a));
  198. case TypeCode.Single:
  199. return checked(-Convert.ToSingle(a));
  200. }
  201. throw new NotImplementedException(
  202. string.Format("No NegeteChecked defined for type {0} ", tc));
  203. }
  204. public static object ConvertToTypeChecked(object a, Type fromType, Type toType)
  205. {
  206. if (a == null && Expression.IsNullable (toType) || !toType.IsValueType)
  207. return a;
  208. if (IsType(toType, a)){
  209. return a;
  210. }
  211. if (Expression.IsPrimitiveConversion(fromType, toType))
  212. return Convert.ChangeType (a, toType);
  213. throw new NotImplementedException (
  214. string.Format ("No Convert defined for type {0} ", toType));
  215. }
  216. public static object ConvertToTypeUnchecked (object a, Type fromType, Type toType)
  217. {
  218. if (a == null && Expression.IsNullable (toType) || !toType.IsValueType)
  219. return a;
  220. if (IsType (toType, a)) {
  221. return a;
  222. }
  223. if (Expression.IsPrimitiveConversion (fromType, toType))
  224. return Conversion.ConvertPrimitiveUnChecked (fromType, toType, a);
  225. throw new NotImplementedException (
  226. string.Format ("No Convert defined for type {0} ", toType));
  227. }
  228. public static bool IsType(Type t, Object o)
  229. {
  230. return t.IsInstanceOfType(o);
  231. }
  232. public static object Negete(object a, TypeCode tc)
  233. {
  234. switch (tc)
  235. {
  236. case TypeCode.Char:
  237. return unchecked(-Convert.ToChar(a));
  238. case TypeCode.Byte:
  239. return unchecked(-Convert.ToByte(a));
  240. case TypeCode.Decimal:
  241. return unchecked(-Convert.ToDecimal(a));
  242. case TypeCode.Double:
  243. return unchecked(-Convert.ToDouble(a));
  244. case TypeCode.Int16:
  245. return unchecked(-Convert.ToInt16(a));
  246. case TypeCode.Int32:
  247. return unchecked(-Convert.ToInt32(a));
  248. case TypeCode.Int64:
  249. return unchecked(-Convert.ToInt64(a));
  250. case TypeCode.UInt16:
  251. return unchecked(-Convert.ToUInt16(a));
  252. case TypeCode.UInt32:
  253. return unchecked(-Convert.ToUInt32(a));
  254. case TypeCode.SByte:
  255. return unchecked(-Convert.ToSByte(a));
  256. case TypeCode.Single:
  257. return unchecked(-Convert.ToSingle(a));
  258. }
  259. throw new NotImplementedException(
  260. string.Format("No Negete defined for type {0} ", tc));
  261. }
  262. public static object RightShift(object a, int n, TypeCode tc)
  263. {
  264. switch (tc)
  265. {
  266. case TypeCode.Int16:
  267. return Convert.ToInt16(a) >> n;
  268. case TypeCode.Int32:
  269. return Convert.ToInt32(a) >> n;
  270. case TypeCode.Int64:
  271. return Convert.ToInt64(a) >> n;
  272. case TypeCode.UInt16:
  273. return Convert.ToUInt16(a) >> n;
  274. case TypeCode.UInt32:
  275. return Convert.ToUInt32(a) >> n;
  276. case TypeCode.UInt64:
  277. return Convert.ToUInt64(a) >> n;
  278. }
  279. throw new NotImplementedException(
  280. string.Format("No right shift defined for type {0} ", tc));
  281. }
  282. public static object LeftShift(object a, int n, TypeCode tc)
  283. {
  284. switch (tc)
  285. {
  286. case TypeCode.Int16:
  287. return Convert.ToInt16(a) << n;
  288. case TypeCode.Int32:
  289. return Convert.ToInt32(a) << n;
  290. case TypeCode.Int64:
  291. return Convert.ToInt64(a) << n;
  292. case TypeCode.UInt16:
  293. return Convert.ToUInt16(a) << n;
  294. case TypeCode.UInt32:
  295. return Convert.ToUInt32(a) << n;
  296. case TypeCode.UInt64:
  297. return Convert.ToUInt64(a) << n;
  298. }
  299. throw new NotImplementedException(
  300. string.Format("No right shift defined for type {0} ", tc));
  301. }
  302. private static Decimal Evaluate(Decimal a, Decimal b, ExpressionType et)
  303. {
  304. switch (et)
  305. {
  306. case ExpressionType.Add:
  307. return unchecked(a + b);
  308. case ExpressionType.AddChecked:
  309. return checked(a + b);
  310. case ExpressionType.Subtract:
  311. return unchecked(a - b);
  312. case ExpressionType.SubtractChecked:
  313. return checked(a - b);
  314. case ExpressionType.Multiply:
  315. return unchecked(a * b);
  316. case ExpressionType.MultiplyChecked:
  317. return checked(a * b);
  318. case ExpressionType.Divide:
  319. return a / b;
  320. case ExpressionType.Modulo:
  321. return a % b;
  322. }
  323. throw new NotImplementedException(
  324. string.Format("Expression with Node type {0}", et));
  325. }
  326. private static Double Evaluate(Double a, Double b, ExpressionType et)
  327. {
  328. switch (et)
  329. {
  330. case ExpressionType.Add:
  331. return unchecked(a + b);
  332. case ExpressionType.AddChecked:
  333. return checked(a + b);
  334. case ExpressionType.Subtract:
  335. return unchecked(a - b);
  336. case ExpressionType.SubtractChecked:
  337. return checked(a - b);
  338. case ExpressionType.Multiply:
  339. return unchecked(a * b);
  340. case ExpressionType.MultiplyChecked:
  341. return checked(a * b);
  342. case ExpressionType.Divide:
  343. return a / b;
  344. case ExpressionType.Modulo:
  345. return a % b;
  346. case ExpressionType.Power:
  347. return System.Math.Pow(a, b);
  348. }
  349. throw new NotImplementedException(
  350. string.Format("Expression with Node type {0}", et));
  351. }
  352. private static Int32 Evaluate(Int16 a, Int16 b, ExpressionType et)
  353. {
  354. switch (et)
  355. {
  356. case ExpressionType.Add:
  357. return unchecked(a + b);
  358. case ExpressionType.AddChecked:
  359. return checked(a + b);
  360. case ExpressionType.Subtract:
  361. return unchecked(a - b);
  362. case ExpressionType.SubtractChecked:
  363. return checked(a - b);
  364. case ExpressionType.Multiply:
  365. return unchecked(a * b);
  366. case ExpressionType.MultiplyChecked:
  367. return checked(a * b);
  368. case ExpressionType.Divide:
  369. return a / b;
  370. case ExpressionType.Modulo:
  371. return a % b;
  372. case ExpressionType.ExclusiveOr:
  373. return a ^ b;
  374. case ExpressionType.And:
  375. return a & b;
  376. case ExpressionType.Or:
  377. return a | b;
  378. }
  379. throw new NotImplementedException(
  380. string.Format("Expression with Node type {0}", et));
  381. }
  382. private static Int32 Evaluate(Int32 a, Int32 b, ExpressionType et)
  383. {
  384. switch (et)
  385. {
  386. case ExpressionType.Add:
  387. return unchecked(a + b);
  388. case ExpressionType.AddChecked:
  389. return checked(a + b);
  390. case ExpressionType.Subtract:
  391. return unchecked(a - b);
  392. case ExpressionType.SubtractChecked:
  393. return checked(a - b);
  394. case ExpressionType.Multiply:
  395. return unchecked(a * b);
  396. case ExpressionType.MultiplyChecked:
  397. return checked(a * b);
  398. case ExpressionType.Divide:
  399. return a / b;
  400. case ExpressionType.Modulo:
  401. return a % b;
  402. case ExpressionType.ExclusiveOr:
  403. return a ^ b;
  404. case ExpressionType.And:
  405. return a & b;
  406. case ExpressionType.Or:
  407. return a | b;
  408. }
  409. throw new NotImplementedException(
  410. string.Format("Expression with Node type {0}", et));
  411. }
  412. private static Int64 Evaluate(Int64 a, Int64 b, ExpressionType et)
  413. {
  414. switch (et)
  415. {
  416. case ExpressionType.Add:
  417. return unchecked(a + b);
  418. case ExpressionType.AddChecked:
  419. return checked(a + b);
  420. case ExpressionType.Subtract:
  421. return unchecked(a - b);
  422. case ExpressionType.SubtractChecked:
  423. return checked(a - b);
  424. case ExpressionType.Multiply:
  425. return unchecked(a * b);
  426. case ExpressionType.MultiplyChecked:
  427. return checked(a * b);
  428. case ExpressionType.Divide:
  429. return a / b;
  430. case ExpressionType.Modulo:
  431. return a % b;
  432. case ExpressionType.ExclusiveOr:
  433. return a ^ b;
  434. case ExpressionType.And:
  435. return a & b;
  436. case ExpressionType.Or:
  437. return a | b;
  438. }
  439. throw new NotImplementedException(
  440. string.Format("Expression with Node type {0}", et));
  441. }
  442. private static Int32 Evaluate(UInt16 a, UInt16 b, ExpressionType et)
  443. {
  444. switch (et)
  445. {
  446. case ExpressionType.Add:
  447. return unchecked(a + b);
  448. case ExpressionType.AddChecked:
  449. return checked(a + b);
  450. case ExpressionType.Subtract:
  451. return unchecked(a - b);
  452. case ExpressionType.SubtractChecked:
  453. return checked((UInt16)(a - b));
  454. case ExpressionType.Multiply:
  455. return unchecked(a * b);
  456. case ExpressionType.MultiplyChecked:
  457. return checked(a * b);
  458. case ExpressionType.Divide:
  459. return a / b;
  460. case ExpressionType.Modulo:
  461. return a % b;
  462. case ExpressionType.ExclusiveOr:
  463. return a ^ b;
  464. case ExpressionType.And:
  465. return a & b;
  466. case ExpressionType.Or:
  467. return a | b;
  468. }
  469. throw new NotImplementedException(
  470. string.Format("Expression with Node type {0}", et));
  471. }
  472. private static UInt32 Evaluate(UInt32 a, UInt32 b, ExpressionType et)
  473. {
  474. switch (et)
  475. {
  476. case ExpressionType.Add:
  477. return unchecked(a + b);
  478. case ExpressionType.AddChecked:
  479. return checked(a + b);
  480. case ExpressionType.Subtract:
  481. return unchecked(a - b);
  482. case ExpressionType.SubtractChecked:
  483. return checked(a - b);
  484. case ExpressionType.Multiply:
  485. return unchecked(a * b);
  486. case ExpressionType.MultiplyChecked:
  487. return checked(a * b);
  488. case ExpressionType.Divide:
  489. return a / b;
  490. case ExpressionType.Modulo:
  491. return a % b;
  492. case ExpressionType.ExclusiveOr:
  493. return a ^ b;
  494. case ExpressionType.And:
  495. return a & b;
  496. case ExpressionType.Or:
  497. return a | b;
  498. }
  499. throw new NotImplementedException(
  500. string.Format("Expression with Node type {0}", et));
  501. }
  502. private static UInt64 Evaluate(UInt64 a, UInt64 b, ExpressionType et)
  503. {
  504. switch (et)
  505. {
  506. case ExpressionType.Add:
  507. return unchecked(a + b);
  508. case ExpressionType.AddChecked:
  509. return checked(a + b);
  510. case ExpressionType.Subtract:
  511. return unchecked(a - b);
  512. case ExpressionType.SubtractChecked:
  513. return checked(a - b);
  514. case ExpressionType.Multiply:
  515. return unchecked(a * b);
  516. case ExpressionType.MultiplyChecked:
  517. return checked(a * b);
  518. case ExpressionType.Divide:
  519. return a / b;
  520. case ExpressionType.Modulo:
  521. return a % b;
  522. case ExpressionType.ExclusiveOr:
  523. return a ^ b;
  524. case ExpressionType.And:
  525. return a & b;
  526. case ExpressionType.Or:
  527. return a | b;
  528. }
  529. throw new NotImplementedException(
  530. string.Format("Expression with Node type {0}", et));
  531. }
  532. private static object Evaluate(Char a, Char b, ExpressionType et)
  533. {
  534. switch (et)
  535. {
  536. case ExpressionType.ExclusiveOr:
  537. return a ^ b;
  538. case ExpressionType.And:
  539. return a & b;
  540. case ExpressionType.Or:
  541. return a | b;
  542. }
  543. throw new NotImplementedException(
  544. string.Format("Expression with Node type {0}", et));
  545. }
  546. private static Int32 Evaluate(SByte a, SByte b, ExpressionType et)
  547. {
  548. switch (et)
  549. {
  550. case ExpressionType.Add:
  551. return unchecked(a + b);
  552. case ExpressionType.AddChecked:
  553. return checked(a + b);
  554. case ExpressionType.Subtract:
  555. return unchecked(a - b);
  556. case ExpressionType.SubtractChecked:
  557. return checked(a - b);
  558. case ExpressionType.Multiply:
  559. return unchecked(a * b);
  560. case ExpressionType.MultiplyChecked:
  561. return checked(a * b);
  562. case ExpressionType.Divide:
  563. return a / b;
  564. case ExpressionType.Modulo:
  565. return a % b;
  566. case ExpressionType.ExclusiveOr:
  567. return a ^ b;
  568. case ExpressionType.And:
  569. return a & b;
  570. case ExpressionType.Or:
  571. return a | b;
  572. }
  573. throw new NotImplementedException(
  574. string.Format("Expression with Node type {0}", et));
  575. }
  576. private static Int32 Evaluate(Byte a, Byte b, ExpressionType et)
  577. {
  578. switch (et)
  579. {
  580. case ExpressionType.Add:
  581. return unchecked(a + b);
  582. case ExpressionType.AddChecked:
  583. return checked(a + b);
  584. case ExpressionType.Subtract:
  585. return unchecked(a - b);
  586. case ExpressionType.SubtractChecked:
  587. return checked(a - b);
  588. case ExpressionType.Multiply:
  589. return unchecked(a * b);
  590. case ExpressionType.MultiplyChecked:
  591. return checked(a * b);
  592. case ExpressionType.Divide:
  593. return a / b;
  594. case ExpressionType.Modulo:
  595. return a % b;
  596. case ExpressionType.ExclusiveOr:
  597. return a ^ b;
  598. case ExpressionType.And:
  599. return a & b;
  600. case ExpressionType.Or:
  601. return a | b;
  602. }
  603. throw new NotImplementedException(
  604. string.Format("Expression with Node type {0}", et));
  605. }
  606. private static Single Evaluate(Single a, Single b, ExpressionType et)
  607. {
  608. switch (et)
  609. {
  610. case ExpressionType.Add:
  611. return unchecked(a + b);
  612. case ExpressionType.AddChecked:
  613. return checked(a + b);
  614. case ExpressionType.Subtract:
  615. return unchecked(a - b);
  616. case ExpressionType.SubtractChecked:
  617. return checked(a - b);
  618. case ExpressionType.Multiply:
  619. return unchecked(a * b);
  620. case ExpressionType.MultiplyChecked:
  621. return checked(a * b);
  622. case ExpressionType.Divide:
  623. return a / b;
  624. case ExpressionType.Modulo:
  625. return a % b;
  626. }
  627. throw new NotImplementedException(
  628. string.Format("Expression with Node type {0}", et));
  629. }
  630. private static bool Evaluate(bool a, bool b, ExpressionType et)
  631. {
  632. switch (et)
  633. {
  634. case ExpressionType.ExclusiveOr:
  635. return a ^ b;
  636. case ExpressionType.And:
  637. return a & b;
  638. case ExpressionType.Or:
  639. return a | b;
  640. }
  641. throw new NotImplementedException(
  642. string.Format("Expression with Node type {0}", et));
  643. }
  644. }
  645. }