diff --git a/includes/form.inc b/includes/form.inc
index bea4914..c146c10 100644
--- a/includes/form.inc
+++ b/includes/form.inc
@@ -2344,41 +2344,66 @@ function form_type_tableselect_value($element, $input = FALSE) {
  * @param $input
  *   (optional) The incoming input to populate the form element. If FALSE, the
  *   element's default value is returned. Defaults to FALSE.
+ * @param $form_state
+ *   (optional) A keyed array containing the current state of the form.
  *
  * @return
  *   The data that will appear in the $element_state['values'] collection for
  *   this element.
+ *
+ * @see form_type_radio_value()
  */
-function form_type_radios_value(&$element, $input = FALSE) {
+function form_type_radios_value(&$element, $input = FALSE, $form_state = array()) {
+  // Radio buttons can have a submitted value or default value of NULL,
+  // indicating that nothing has been selected. However, if NULL is submitted,
+  // _form_builder_handle_input_element() will replace it with an empty string,
+  // which can cause one of the radio buttons to be incorrectly selected (if an
+  // empty string is one of the #options) or the form to fail validation (if it
+  // is not one of the #options). To prevent this, the #has_garbage_value
+  // property is set, to signify to the form API that its standard handling of
+  // NULL values should not be used.
+  if (!isset($input) || ($input === FALSE && !isset($element['#default_value']))) {
+    $element['#has_garbage_value'] = TRUE;
+  }
+
+  // Besides the above, the form API's standard value handling is correct for
+  // radios in the case where input was submitted.
   if ($input !== FALSE) {
-    // There may not be a submitted value for multiple radio buttons, if none of
-    // the options was checked by default. If there is no submitted input value
-    // for this element (NULL), _form_builder_handle_input_element()
-    // automatically attempts to use the #default_value (if set) or an empty
-    // string (''). However, an empty string would fail validation in
-    // _form_validate(), in case it is not contained in the list of allowed
-    // values in #options.
-    if (!isset($input)) {
-      // Signify a garbage value to disable the #default_value handling and take
-      // over NULL as #value.
-      $element['#has_garbage_value'] = TRUE;
-      // There was a user submission so validation is a must. If this element is
-      // #required, then an appropriate error message will be output. While an
-      // optional #type 'radios' does not necessarily make sense from a user
-      // interaction perspective, there may be use-cases for that and it is not
-      // the job of Form API to artificially limit possibilities.
-      $element['#needs_validation'] = TRUE;
-    }
-    // The value stays the same, but the flags above will ensure it is
-    // processed properly.
     return $input;
   }
-  elseif (isset($element['#default_value'])) {
+  // However, because we let NULL values through, the form API may sometimes
+  // request default value handling for radios even when input was submitted.
+  // Make sure we don't replace the submitted NULL value with the default value
+  // in that case.
+  elseif (isset($element['#default_value']) && empty($form_state['input'])) {
     return $element['#default_value'];
   }
 }
 
 /**
+ * Form value callback: Determines the value for a #type radio form element.
+ *
+ * @param $element
+ *   The form element whose value is being populated.
+ * @param $input
+ *   (optional) The incoming input to populate the form element. If FALSE, the
+ *   element's default value is returned. Defaults to FALSE.
+ * @param $form_state
+ *   (optional) A keyed array containing the current state of the form.
+ *
+ * @return
+ *   The data that will appear in the $element_state['values'] collection for
+ *   this element.
+ *
+ * @see form_type_radios_value()
+ */
+function form_type_radio_value(&$element, $input = FALSE, $form_state = array()) {
+  // A single radio button's value is determined the same way as a set of radio
+  // buttons.
+  return form_type_radios_value($element, $input, $form_state);
+}
+
+/**
  * Determines the value for a password_confirm form element.
  *
  * @param $element
@@ -2791,7 +2816,7 @@ function theme_radio($variables) {
   $element['#attributes']['type'] = 'radio';
   element_set_attributes($element, array('id', 'name', '#return_value' => 'value'));
 
-  if (isset($element['#return_value']) && $element['#value'] !== FALSE && $element['#value'] == $element['#return_value']) {
+  if (isset($element['#return_value']) && isset($element['#value']) && $element['#value'] == $element['#return_value']) {
     $element['#attributes']['checked'] = 'checked';
   }
   _form_set_class($element, array('form-radio'));
@@ -3025,9 +3050,7 @@ function form_process_radios($element) {
         // The key is sanitized in drupal_attributes() during output from the
         // theme function.
         '#return_value' => $key,
-        // Use default or FALSE. A value of FALSE means that the radio button is
-        // not 'checked'.
-        '#default_value' => isset($element['#default_value']) ? $element['#default_value'] : FALSE,
+        '#default_value' => isset($element['#default_value']) ? $element['#default_value'] : NULL,
         '#attributes' => $element['#attributes'],
         '#parents' => $element['#parents'],
         '#id' => drupal_html_id('edit-' . implode('-', $parents_for_id)),
diff --git a/modules/field/modules/options/options.module b/modules/field/modules/options/options.module
index 3862ba7..5c52fde 100644
--- a/modules/field/modules/options/options.module
+++ b/modules/field/modules/options/options.module
@@ -106,16 +106,15 @@ function options_field_widget_form(&$form, &$form_state, $field, $instance, $lan
         $default_value = array(key($options));
       }
 
-      // If this is a single-value field, take the first default value, or
-      // default to NULL so that the form element is properly recognized as
-      // not having a default value.
+      // Radio buttons need a scalar value. Therefore, take the first default
+      // value if there is one, or use NULL otherwise (so that the form element
+      // is properly recognized as not having a default value).
       if (!$multiple) {
         $default_value = $default_value ? reset($default_value) : NULL;
       }
 
       $element += array(
         '#type' => $multiple ? 'checkboxes' : 'radios',
-        // Radio buttons need a scalar value.
         '#default_value' => $default_value,
         '#options' => $options,
       );
