سؤال

فعلت بعض التجارب مع النقطة العائمة حسابات للحد من فقدان الدقة.أنا تعثرت عبر phenomen أريد أن تظهر هنا ونأمل الحصول على تفسير.

عندما أكتب

print 1.0 / (1.0 / 60.0)

والنتيجة هي

60.0024000960

عندما أكتب نفس الصيغة و هل صريحة الصب float

print cast(1.0 as float) / (cast(1.0 as float) / cast(60.0 as float))

والنتيجة هي

60

حتى الآن أعتقد أن رقمية حرفية مع المنازل العشرية تلقائيا يعامل float القيم المناسبة الدقة.الصب real يظهر نفس النتيجة مثل الصب float.

  • هناك بعض الوثائق كيفية SQL Server يقيم رقمية حرفية?
  • ما نوع البيانات هي تلك حرفية?
  • هل علي حقا أن يلقي لهم float الحصول على أفضل دقة (الذي يبدو وكأنه مفارقة لي :)?
  • هل هناك طريقة أسهل من التبعثر بلدي الصيغ مع يلقي?
هل كانت مفيدة؟

المحلول

يستخدم SQL Server أصغر ممكن نوع البيانات.

عند تشغيل هذا البرنامج النصي

SELECT SQL_VARIANT_PROPERTY(1.0, 'BaseType')
SELECT SQL_VARIANT_PROPERTY(1.0, 'Precision')
SELECT SQL_VARIANT_PROPERTY(1.0, 'Scale')
SELECT SQL_VARIANT_PROPERTY(1.0, 'TotalBytes')

سترى أن SQL Server ضمنا استخدام رقمي(2 ، 1) على نوع البيانات.
التقسيم حسب 60.0 يحول النتيجة إلى رقمية(8, 6).
الحساب النهائي يحول النتيجة إلى رقمية(17, 10).


تحرير

مأخوذة من كتب SQL Server عبر إنترنت نوع بيانات التحويل

في عبارات SQL للعمليات المستمرة مع الفاصلة العشرية تلقائيا تحويلها إلى بيانات رقمية قيمة ، باستخدام الحد الأدنى من الدقة والحجم من الضروري.على سبيل المثال, المستمر 12.345 يتم تحويلها إلى قيمة رقمية بدقة 5 ، جدول 3.

نصائح أخرى

نعم، يتعين عليك في كثير من الأحيان رميها لتطفو للحصول على دقة أفضل.رأيي في ذلك:

للحصول على دقة أفضل، قم بإلقاء الكسور العشرية قبل إجراء العمليات الحسابية

أعتقد أنه ينبغي أن يفهم ما يجري وراء الكواليس للرجوع إليها في المستقبل في حالات مماثلة.

الحرفي القيم العددية مع الفاصلة العشرية باستثناء العلمي تمثل عشري نوع البيانات التي يتم تخزينها أصغر من الممكن النوع عشري.نفس الاقتباس كما يفن Keersmaekers من:https://msdn.microsoft.com/en-us/library/ms191530%28SQL.90%29.aspx#_decimal

في عبارات SQL للعمليات المستمرة مع العشرية تلقائيا تحويلها إلى بيانات رقمية القيمة ، وذلك باستخدام الحد الأدنى الدقة و الحجم اللازمة.على سبيل المثال, المستمر 12.345 هو تحويلها إلى قيمة رقمية بدقة 5 و سلم 3.

زائدة الأصفار على يمين الفاصلة العشرية تحديد نطاق.الأصفار البادئة اليسرى من العشرية يتم تجاهلها.

بعض الأمثلة:

1.0  -> Decimal(2,1)
60.0 -> Decimal(3,1)
1.00 -> Decimal(3,2)
01.0 -> Decimal (2,1)

نقطة أخرى للنظر نوع البيانات الأسبقية.عندما عامل يجمع بين تعبيرين من مختلف أنواع البيانات ، قواعد البيانات نوع الأسبقية تحديد نوع البيانات مع انخفاض الأسبقية يتم تحويلها إلى نوع البيانات مع ارتفاع الأسبقية.و نقطة أخرى للنظر هو أن نقوم العمليات الحسابية على العشرية أنواع الناتجة النوع عشري ، أيالدقة و الحجم تعتمد على كل المعاملات و العملية نفسها.هذا هو موضح في الوثيقة الدقة حجم و طول.

لذا جزء من التعبير بين قوسين

( 1.0 / 60.0 ) is evaluated to 0.016666 and the resulting type is Decimal (8,6)

باستخدام القواعد أعلاه عن الدقة و حجم العشرية التعبيرات.وبالإضافة إلى ذلك التقريب الخاصة banker أو التقريب حتى يتم استخدامها.من المهم أن نلاحظ التقريب مختلفة عن العشرية و نوع تعويم تستخدم.إذا واصلنا التعبير

1.0 / 0.016666 is evaluated to 60.002400096 and the resulting type is Decimal (17,10)

وبالتالي فإن جزءا من التناقض يرجع إلى التقريب مختلفة تستخدم في العشرية أنواع من تعويم.

وفقا للقواعد المذكورة أعلاه سيكون كافيا لاستخدام واحد فقط يلقي داخل قوسين.كل الحرفي سيتم ترقيته إلى تعويم وفقا نوع البيانات قواعد الأسبقية.

1.0 / (1.0 / cast(60.0 as float))

واحد أكثر الشيء المهم.حتى هذا تطفو التعبير لا حساب الدقيق النتيجة.هو فقط بحيث الأمامية (SSMS أو أيا كان) تقريب القيمة إلى (اعتقد) الدقة 6 أرقام ثم باقتطاع زائدة الأصفار.لذلك أي1.000001 يصبح 1.

بسيطة, أليس كذلك ؟

لكتابة تعبير تعويم ثابت، حاول استخدام الترميز العلمي:

select (1.0E0 / (1.0E0 / 60.0E0))

والنتيجة هي 60.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top